static inline bool vr_my_pkt(unsigned char *pkt_mac, struct vr_interface *vif) { /* * Packet is destined to us if: * 1) IF destination MAC is our Mac * 2) If VIF is service interface */ if (VR_MAC_CMP(pkt_mac, vif->vif_mac) || vif_is_service(vif)) return true; return false; }
/* * vr_interface_input() is invoked if a packet ingresses an interface. * This function demultiplexes the packet to right input * function depending on the protocols enabled on the VIF */ unsigned int vr_virtual_input(unsigned short vrf, struct vr_interface *vif, struct vr_packet *pkt, unsigned short vlan_id) { struct vr_forwarding_md fmd; vr_init_forwarding_md(&fmd); fmd.fmd_vlan = vlan_id; fmd.fmd_dvrf = vrf; if (vif->vif_flags & VIF_FLAG_MIRROR_RX) { fmd.fmd_dvrf = vif->vif_vrf; vr_mirror(vif->vif_router, vif->vif_mirror_id, pkt, &fmd); } if (vr_pkt_type(pkt, 0, &fmd) < 0) { vif_drop_pkt(vif, pkt, 1); return 0; } /* * we really do not allow any broadcast packets from interfaces * that are part of transparent service chain, since transparent * service chain bridges packets across vrf (and hence loops can * happen) */ if ((pkt->vp_flags & VP_FLAG_MULTICAST) && (vif_is_service(vif))) { vif_drop_pkt(vif, pkt, 1); return 0; } if (!vr_flow_forward(pkt->vp_if->vif_router, pkt, &fmd)) return 0; vr_bridge_input(vif->vif_router, pkt, &fmd); return 0; }
static inline void vr_get_flow_key(struct vr_flow_key *key, uint16_t vlan, struct vr_packet *pkt, unsigned int sip, unsigned int dip, unsigned char proto, unsigned short sport, unsigned short dport) { unsigned short nh_id; /* copy both source and destinations */ key->key_src_ip = sip; key->key_dest_ip = dip; key->key_proto = proto; key->key_zero = 0; if (vif_is_fabric(pkt->vp_if) && pkt->vp_nh) { nh_id = pkt->vp_nh->nh_id; } else if (vif_is_service(pkt->vp_if)) { nh_id = vif_vrf_table_get_nh(pkt->vp_if, vlan); } else { nh_id = pkt->vp_if->vif_nh_id; } key->key_nh_id = nh_id; switch (proto) { case VR_IP_PROTO_TCP: case VR_IP_PROTO_UDP: case VR_IP_PROTO_ICMP: key->key_src_port = sport; key->key_dst_port = dport; break; default: key->key_src_port = key->key_dst_port = 0; break; } return; }