/* Must be called with rcu_read_lock. */ static void netdev_port_receive(struct sk_buff *skb) { struct vport *vport; vport = ovs_netdev_get_vport(skb->dev); if (unlikely(!vport)) goto error; if (unlikely(skb_warn_if_lro(skb))) goto error; /* Make our own copy of the packet. Otherwise we will mangle the * packet for anyone who came before us (e.g. tcpdump via AF_PACKET). */ skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) return; skb_push(skb, ETH_HLEN); ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN); ovs_vport_receive(vport, skb, skb_tunnel_info(skb)); return; error: kfree_skb(skb); }
/* Must be called with rcu_read_lock. */ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) { if (unlikely(!vport)) goto error; if (unlikely(skb_warn_if_lro(skb))) goto error; /* Make our own copy of the packet. Otherwise we will mangle the * packet for anyone who came before us (e.g. tcpdump via AF_PACKET). * (No one comes after us, since we tell handle_bridge() that we took * the packet.) */ skb = skb_share_check(skb, GFP_ATOMIC); if (unlikely(!skb)) return; skb_push(skb, ETH_HLEN); ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN); ovs_vport_receive(vport, skb, NULL); return; error: kfree_skb(skb); }
static int set_eth_addr(struct sk_buff *skb, const struct ovs_key_ethernet *eth_key) { int err; err = make_writable(skb, ETH_HLEN); if (unlikely(err)) return err; skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2); ether_addr_copy(eth_hdr(skb)->h_source, eth_key->eth_src); ether_addr_copy(eth_hdr(skb)->h_dest, eth_key->eth_dst); ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2); return 0; }
static int set_eth_addr(struct sk_buff *skb, struct sw_flow_key *flow_key, const struct ovs_key_ethernet *key, const struct ovs_key_ethernet *mask) { int err; err = skb_ensure_writable(skb, ETH_HLEN); if (unlikely(err)) return err; skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2); //added by daolicloud if (ETH_P_ARP == ntohs(eth_hdr(skb)->h_proto)) { struct arphdr *p = arp_hdr(skb); unsigned char ip[4]; struct arpft *pdata = (struct arpft *)((unsigned char *)p + sizeof(struct arphdr)); if(ARPOP_REQUEST == ntohs(p->ar_op)) { p->ar_op = htons(ARPOP_REPLY); memcpy(ip, pdata->ar_sip, 4); memcpy(pdata->ar_sha, key->eth_src, ETH_ALEN); memcpy(pdata->ar_sip, pdata->ar_tip, 4); memcpy(pdata->ar_tha, eth_hdr(skb)->h_source, ETH_ALEN); memcpy(pdata->ar_tip, ip, 4); memcpy(eth_hdr(skb)->h_dest, eth_hdr(skb)->h_source, ETH_ALEN); } else { ether_addr_copy_masked(eth_hdr(skb)->h_dest, key->eth_dst, mask->eth_dst); } } else { ether_addr_copy_masked(eth_hdr(skb)->h_dest, key->eth_dst, mask->eth_dst); } //// ether_addr_copy_masked(eth_hdr(skb)->h_source, key->eth_src, mask->eth_src); ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2); ether_addr_copy(flow_key->eth.src, eth_hdr(skb)->h_source); ether_addr_copy(flow_key->eth.dst, eth_hdr(skb)->h_dest); return 0; }
static int set_eth_addr(struct sk_buff *skb, struct sw_flow_key *flow_key, const struct ovs_key_ethernet *key, const struct ovs_key_ethernet *mask) { int err; err = skb_ensure_writable(skb, ETH_HLEN); if (unlikely(err)) return err; skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2); ether_addr_copy_masked(eth_hdr(skb)->h_source, key->eth_src, mask->eth_src); ether_addr_copy_masked(eth_hdr(skb)->h_dest, key->eth_dst, mask->eth_dst); ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2); ether_addr_copy(flow_key->eth.src, eth_hdr(skb)->h_source); ether_addr_copy(flow_key->eth.dst, eth_hdr(skb)->h_dest); return 0; }