From 83674787d5d12723524b524f1407a9939deb87ea Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 5 Feb 2019 17:21:21 +0100 Subject: [PATCH] forecast: Only reinject packets that are marked or from the configured interface This seems to avoid broadcast loops (i.e. processing and reinjecting the same broadcast packet over and over again) as the packets we send via AF_PACKET socket are neither marked nor from that interface. --- src/libcharon/plugins/forecast/forecast_forwarder.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libcharon/plugins/forecast/forecast_forwarder.c b/src/libcharon/plugins/forecast/forecast_forwarder.c index ce39097370..42b57b10bc 100644 --- a/src/libcharon/plugins/forecast/forecast_forwarder.c +++ b/src/libcharon/plugins/forecast/forecast_forwarder.c @@ -317,9 +317,15 @@ static void join_groups(private_kernel_listener_t *this, struct sockaddr *addr) /** * Attach the socket filter to the socket */ -static bool attach_filter(int fd, uint32_t broadcast) +static bool attach_filter(int fd, uint32_t broadcast, uint32_t ifindex) { struct sock_filter filter_code[] = { + /* handle any marked packets (from clients) */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, SKF_AD_OFF+SKF_AD_MARK), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 2), + /* and those from the internal interface */ + BPF_STMT(BPF_LD+BPF_B+BPF_ABS, SKF_AD_OFF+SKF_AD_IFINDEX), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ifindex, 0, 5), /* destination address: is ... */ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct iphdr, daddr)), /* broadcast, as received from the local network */ @@ -390,7 +396,7 @@ static void setup_interface(private_kernel_listener_t *this) DBG1(DBG_NET, "using forecast interface %s", current->ifa_name); this->ifindex = get_ifindex(this, current->ifa_name); in = (struct sockaddr_in*)current->ifa_broadaddr; - attach_filter(this->pkt, in->sin_addr.s_addr); + attach_filter(this->pkt, in->sin_addr.s_addr, this->ifindex); join_groups(this, current->ifa_addr); host = host_create_from_sockaddr(current->ifa_broadaddr); if (host)