Commit 2c38de4c authored by Nicolas Cavallari's avatar Nicolas Cavallari Committed by Patrick McHardy

netfilter: fix looped (broad|multi)cast's MAC handling

By default, when broadcast or multicast packet are sent from a local
application, they are sent to the interface then looped by the kernel
to other local applications, going throught netfilter hooks in the
process.

These looped packet have their MAC header removed from the skb by the
kernel looping code. This confuse various netfilter's netlink queue,
netlink log and the legacy ip_queue, because they try to extract a
hardware address from these packets, but extracts a part of the IP
header instead.

This patch prevent NFQUEUE, NFLOG and ip_QUEUE to include a MAC header
if there is none in the packet.
Signed-off-by: default avatarNicolas Cavallari <cavallar@lri.fr>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent db898aa2
...@@ -203,7 +203,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) ...@@ -203,7 +203,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
else else
pmsg->outdev_name[0] = '\0'; pmsg->outdev_name[0] = '\0';
if (entry->indev && entry->skb->dev) { if (entry->indev && entry->skb->dev &&
entry->skb->mac_header != entry->skb->network_header) {
pmsg->hw_type = entry->skb->dev->type; pmsg->hw_type = entry->skb->dev->type;
pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addrlen = dev_parse_header(entry->skb,
pmsg->hw_addr); pmsg->hw_addr);
......
...@@ -204,7 +204,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp) ...@@ -204,7 +204,8 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
else else
pmsg->outdev_name[0] = '\0'; pmsg->outdev_name[0] = '\0';
if (entry->indev && entry->skb->dev) { if (entry->indev && entry->skb->dev &&
entry->skb->mac_header != entry->skb->network_header) {
pmsg->hw_type = entry->skb->dev->type; pmsg->hw_type = entry->skb->dev->type;
pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr); pmsg->hw_addrlen = dev_parse_header(entry->skb, pmsg->hw_addr);
} }
......
...@@ -456,7 +456,8 @@ __build_packet_message(struct nfulnl_instance *inst, ...@@ -456,7 +456,8 @@ __build_packet_message(struct nfulnl_instance *inst,
if (skb->mark) if (skb->mark)
NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark));
if (indev && skb->dev) { if (indev && skb->dev &&
skb->mac_header != skb->network_header) {
struct nfulnl_msg_packet_hw phw; struct nfulnl_msg_packet_hw phw;
int len = dev_parse_header(skb, phw.hw_addr); int len = dev_parse_header(skb, phw.hw_addr);
if (len > 0) { if (len > 0) {
......
...@@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, ...@@ -335,7 +335,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
if (entskb->mark) if (entskb->mark)
NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark)); NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
if (indev && entskb->dev) { if (indev && entskb->dev &&
entskb->mac_header != entskb->network_header) {
struct nfqnl_msg_packet_hw phw; struct nfqnl_msg_packet_hw phw;
int len = dev_parse_header(entskb, phw.hw_addr); int len = dev_parse_header(entskb, phw.hw_addr);
if (len) { if (len) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment