/* Add bridge to datapath manager. */ lagopus_result_t dpmgr_bridge_add(struct dpmgr *dpmgr, const char *bridge_name, uint64_t dpid) { lagopus_result_t ret; ret = bridge_add(&dpmgr->bridge_list, bridge_name, dpid); return ret; }
static int __bridge_table_add(struct vr_route_req *rt) { int ret; unsigned short flags, i; struct vr_bridge_entry *be; be = bridge_add(rt->rtr_req.rtr_rid, rt->rtr_req.rtr_vrf_id, rt->rtr_req.rtr_mac, rt->rtr_req.rtr_nh_id); if (!be) return -ENOMEM; rt->rtr_req.rtr_label_flags = VR_BRIDGE_FLAG_MASK(rt->rtr_req.rtr_label_flags); if (rt->rtr_req.rtr_label_flags & VR_BE_LABEL_VALID_FLAG) be->be_label = rt->rtr_req.rtr_label; /* * attempt the change for some number of times, if the set * turns out to be contested */ ret = -EAGAIN; for (i = 0; i < 10; i++) { flags = be->be_flags & VR_BE_VALID_FLAG; if (__sync_bool_compare_and_swap(&be->be_flags, flags, flags | rt->rtr_req.rtr_label_flags)) { ret = 0; break; } } rt->rtr_req.rtr_index = be->be_hentry.hentry_index; return ret; }
int brport(char *ifname, int ifs, int argc, char **argv) { int set, i; struct brc *x; if (NO_ARG(argv[0])) { set = 0; argv++; argc--; } else set = 1; x = (struct brc *) genget(argv[0], (char **)brps, sizeof(struct brc)); if (x == 0) { printf("%% Internal error - Invalid argument %s\n", argv[0]); return 0; } else if (Ambiguous(x)) { printf("%% Internal error - Ambiguous argument %s\n", argv[0]); return 0; } argv++; argc--; if (argc == 0) { printf("%% %s <if> [if]...\n", x->name); printf("%% no %s <if> [if]...\n", x->name); return(0); } for (i = 0; i < argc; i++) { if (!is_valid_ifname(argv[i]) || is_bridge(ifs, argv[i])) { printf("%% Invalid interface name %s\n", argv[i]); continue; } switch(x->type) { case BRPORT_MEMBER: if (set) { /* adding a member activates a bridge */ set_ifflag(ifs, ifname, IFF_UP); bridge_add(ifs, ifname, argv[i]); } else bridge_delete(ifs, ifname, argv[i]); break; case BRPORT_SPAN: if (set) bridge_addspan(ifs, ifname, argv[i]); else bridge_delspan(ifs, ifname, argv[i]); break; case BRPORT_BLOCKNONIP: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_BLOCKNONIP); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_BLOCKNONIP); break; case BRPORT_DISCOVER: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_DISCOVER); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_DISCOVER); break; case BRPORT_LEARN: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_LEARNING); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_LEARNING); break; case BRPORT_STP: if (set) bridge_ifsetflag(ifs, ifname, argv[i], IFBIF_STP); else bridge_ifclrflag(ifs, ifname, argv[i], IFBIF_STP); break; } } return(0); }
unsigned int vr_bridge_learn(struct vrouter *router, struct vr_packet *pkt, struct vr_forwarding_md *fmd) { int ret = 0, lock, valid_src; unsigned int trap_reason; bool trap = false; struct vr_eth *eth; struct vr_packet *pkt_c; struct vr_nexthop *nh = NULL; struct vr_bridge_entry *be; eth = (struct vr_eth *)pkt_data(pkt); if (!eth) return 0; if (IS_MAC_BMCAST(eth->eth_smac)) return 0; be = bridge_lookup(eth->eth_smac, fmd); if (be) { nh = be->be_nh; } if (!nh) { be = bridge_lookup((uint8_t *)vr_bcast_mac, fmd); if (be) { nh = be->be_nh; } if (!nh) return 0; lock = bridge_table_lock(pkt->vp_if, eth->eth_smac); if (lock < 0) return 0; be = bridge_add(0, fmd->fmd_dvrf, eth->eth_smac, nh->nh_id); bridge_table_unlock(pkt->vp_if, eth->eth_smac, lock); if (!be) return -ENOMEM; trap_reason = AGENT_TRAP_MAC_LEARN; trap = true; } else { if (!(be->be_flags & VR_BE_MAC_MOVED_FLAG) && (nh->nh_validate_src)) { valid_src = nh->nh_validate_src(pkt, nh, fmd, NULL); if (valid_src != NH_SOURCE_VALID) { ret = vr_bridge_set_route_flags(be, VR_BE_MAC_MOVED_FLAG); if (!ret) { /* trap the packet for mac move */ trap_reason = AGENT_TRAP_MAC_MOVE; trap = true; } ret = 0; } } } __sync_fetch_and_add(&be->be_packets, 1); if (trap) { pkt_c = pkt_cow(pkt, 0); if (!pkt_c) { pkt_c = pkt; ret = -ENOMEM; } vr_trap(pkt_c, fmd->fmd_dvrf, trap_reason, (void *)&be->be_hentry.hentry_index); } return ret; }