Beispiel #1
0
/* 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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
}
Beispiel #4
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;
}