static struct vr_nexthop * bridge_table_lookup(unsigned int vrf_id, struct vr_route_req *rt) { struct vr_bridge_entry *be; struct vr_bridge_entry_key key; if (rt->rtr_req.rtr_index != VR_BE_INVALID_INDEX) { be = vr_get_hentry_by_index(vn_rtable, rt->rtr_req.rtr_index); if (!be) return NULL; rt->rtr_nh = be->be_nh; if (rt->rtr_req.rtr_mac) VR_MAC_COPY(rt->rtr_req.rtr_mac, be->be_key.be_mac); return rt->rtr_nh; } rt->rtr_nh = NULL; rt->rtr_req.rtr_index = VR_BE_INVALID_INDEX; VR_MAC_COPY(key.be_mac, rt->rtr_req.rtr_mac); key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be = vr_find_bridge_entry(&key); if (be) { if (be->be_flags & VR_BE_FLAG_LABEL_VALID) rt->rtr_req.rtr_label_flags |= VR_RT_LABEL_VALID_FLAG; rt->rtr_req.rtr_label = be->be_label; rt->rtr_nh = be->be_nh; rt->rtr_req.rtr_index = be->be_index; } return rt->rtr_nh; }
unsigned short vr_bridge_route_flags(unsigned int vrf_id, unsigned char *mac) { struct vr_bridge_entry *be; struct vr_bridge_entry_key key; VR_MAC_COPY(key.be_mac, mac); key.be_vrf_id = vrf_id; be = vr_find_bridge_entry(&key); if (be && (be->be_flags & VR_BE_VALID_FLAG)) return be->be_flags; return 0; }
static int bridge_table_delete(struct vr_rtable * _unused, struct vr_route_req *rt) { struct vr_bridge_entry_key key; struct vr_bridge_entry *be; if (!vn_rtable) return -EINVAL; VR_MAC_COPY(key.be_mac, rt->rtr_req.rtr_mac); key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be = vr_find_bridge_entry(&key); if (!be) return -ENOENT; bridge_table_entry_free(vn_rtable, (vr_hentry_t )be, 0, NULL); return 0; }
static struct vr_bridge_entry * bridge_add(unsigned int router_id, unsigned int vrf, uint8_t *mac, int nh_id) { struct vr_bridge_entry *be; struct vr_bridge_entry_key key; struct vr_nexthop *old_nh; VR_MAC_COPY(key.be_mac, mac); key.be_vrf_id = vrf; be = vr_find_bridge_entry(&key); if (!be) { be = vr_find_free_bridge_entry(vrf, mac); if (!be) return NULL; VR_MAC_COPY(be->be_key.be_mac, mac); be->be_key.be_vrf_id = vrf; be->be_packets = 0; be->be_flags = VR_BE_VALID_FLAG; } /* Un ref the old nexthop */ if (be->be_nh_id != nh_id) { old_nh = be->be_nh; be->be_nh = vrouter_get_nexthop(router_id, nh_id); if (be->be_nh) { be->be_nh_id = be->be_nh->nh_id; } else { be->be_nh_id = -1; } if (be->be_flags & VR_BE_MAC_MOVED_FLAG) { be->be_flags &= ~VR_BE_MAC_MOVED_FLAG; } if (old_nh) vrouter_put_nexthop(old_nh); } return be; }
static struct vr_bridge_entry * __bridge_lookup(unsigned int vrf_id, struct vr_route_req *rt) { struct vr_bridge_entry *be; struct vr_bridge_entry_key key; rt->rtr_req.rtr_label_flags = 0; rt->rtr_nh = NULL; if (rt->rtr_req.rtr_index != VR_BE_INVALID_INDEX) { be = (struct vr_bridge_entry *) vr_htable_get_hentry_by_index(vn_rtable, rt->rtr_req.rtr_index); } else { VR_MAC_COPY(key.be_mac, rt->rtr_req.rtr_mac); key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be = vr_find_bridge_entry(&key); } return be; }
static struct vr_nexthop * bridge_table_lookup(unsigned int vrf_id, struct vr_route_req *rt, struct vr_packet *pkt) { struct vr_bridge_entry *be; struct vr_bridge_entry_key key; VR_MAC_COPY(key.be_mac, rt->rtr_req.rtr_mac); key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be = vr_find_bridge_entry(&key); if (be) { if (be->be_flags & VR_BE_FLAG_LABEL_VALID) rt->rtr_req.rtr_label_flags = VR_RT_LABEL_VALID_FLAG; rt->rtr_req.rtr_label = be->be_label; rt->rtr_nh = be->be_nh; return be->be_nh; } return NULL; }
static int __bridge_table_add(struct vr_route_req *rt) { struct vr_bridge_entry *be; struct vr_nexthop *old_nh; struct vr_bridge_entry_key key; VR_MAC_COPY(key.be_mac, rt->rtr_req.rtr_mac); key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be = vr_find_bridge_entry(&key); if (!be) { be = vr_find_free_bridge_entry(rt->rtr_req.rtr_vrf_id, (char *)rt->rtr_req.rtr_mac); if (!be) return -ENOMEM; VR_MAC_COPY(be->be_key.be_mac, rt->rtr_req.rtr_mac); be->be_key.be_vrf_id = rt->rtr_req.rtr_vrf_id; be->be_flags |= VR_BE_FLAG_VALID; } if (be->be_nh != rt->rtr_nh) { /* Un ref the old nexthop */ old_nh = be->be_nh; be->be_nh = vrouter_get_nexthop(rt->rtr_req.rtr_rid, rt->rtr_req.rtr_nh_id); if (old_nh) vrouter_put_nexthop(old_nh); } if (rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG) { be->be_label = rt->rtr_req.rtr_label; be->be_flags |= VR_BE_FLAG_LABEL_VALID; } return 0; }