diff options
Diffstat (limited to 'drivers/net/vrf.c')
-rw-r--r-- | drivers/net/vrf.c | 110 |
1 files changed, 55 insertions, 55 deletions
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 259d5cbacf2c..571bd03ebd81 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -1237,6 +1237,61 @@ static struct sk_buff *vrf_rcv_nfhook(u8 pf, unsigned int hook, return skb; } +static int vrf_prepare_mac_header(struct sk_buff *skb, + struct net_device *vrf_dev, u16 proto) +{ + struct ethhdr *eth; + int err; + + /* in general, we do not know if there is enough space in the head of + * the packet for hosting the mac header. + */ + err = skb_cow_head(skb, LL_RESERVED_SPACE(vrf_dev)); + if (unlikely(err)) + /* no space in the skb head */ + return -ENOBUFS; + + __skb_push(skb, ETH_HLEN); + eth = (struct ethhdr *)skb->data; + + skb_reset_mac_header(skb); + + /* we set the ethernet destination and the source addresses to the + * address of the VRF device. + */ + ether_addr_copy(eth->h_dest, vrf_dev->dev_addr); + ether_addr_copy(eth->h_source, vrf_dev->dev_addr); + eth->h_proto = htons(proto); + + /* the destination address of the Ethernet frame corresponds to the + * address set on the VRF interface; therefore, the packet is intended + * to be processed locally. + */ + skb->protocol = eth->h_proto; + skb->pkt_type = PACKET_HOST; + + skb_postpush_rcsum(skb, skb->data, ETH_HLEN); + + skb_pull_inline(skb, ETH_HLEN); + + return 0; +} + +/* prepare and add the mac header to the packet if it was not set previously. + * In this way, packet sniffers such as tcpdump can parse the packet correctly. + * If the mac header was already set, the original mac header is left + * untouched and the function returns immediately. + */ +static int vrf_add_mac_header_if_unset(struct sk_buff *skb, + struct net_device *vrf_dev, + u16 proto) +{ + if (skb_mac_header_was_set(skb)) + return 0; + + return vrf_prepare_mac_header(skb, vrf_dev, proto); +} + #if IS_ENABLED(CONFIG_IPV6) /* neighbor handling is done with actual device; do not want * to flip skb->dev for those ndisc packets. This really fails @@ -1310,61 +1365,6 @@ static void vrf_ip6_input_dst(struct sk_buff *skb, struct net_device *vrf_dev, skb_dst_set(skb, &rt6->dst); } -static int vrf_prepare_mac_header(struct sk_buff *skb, - struct net_device *vrf_dev, u16 proto) -{ - struct ethhdr *eth; - int err; - - /* in general, we do not know if there is enough space in the head of - * the packet for hosting the mac header. - */ - err = skb_cow_head(skb, LL_RESERVED_SPACE(vrf_dev)); - if (unlikely(err)) - /* no space in the skb head */ - return -ENOBUFS; - - __skb_push(skb, ETH_HLEN); - eth = (struct ethhdr *)skb->data; - - skb_reset_mac_header(skb); - - /* we set the ethernet destination and the source addresses to the - * address of the VRF device. - */ - ether_addr_copy(eth->h_dest, vrf_dev->dev_addr); - ether_addr_copy(eth->h_source, vrf_dev->dev_addr); - eth->h_proto = htons(proto); - - /* the destination address of the Ethernet frame corresponds to the - * address set on the VRF interface; therefore, the packet is intended - * to be processed locally. - */ - skb->protocol = eth->h_proto; - skb->pkt_type = PACKET_HOST; - - skb_postpush_rcsum(skb, skb->data, ETH_HLEN); - - skb_pull_inline(skb, ETH_HLEN); - - return 0; -} - -/* prepare and add the mac header to the packet if it was not set previously. - * In this way, packet sniffers such as tcpdump can parse the packet correctly. - * If the mac header was already set, the original mac header is left - * untouched and the function returns immediately. - */ -static int vrf_add_mac_header_if_unset(struct sk_buff *skb, - struct net_device *vrf_dev, - u16 proto) -{ - if (skb_mac_header_was_set(skb)) - return 0; - - return vrf_prepare_mac_header(skb, vrf_dev, proto); -} - static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev, struct sk_buff *skb) { |