Example #1
0
func ParseEvpnMacAdvArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
	if len(args) < 4 {
		return nil, nil, fmt.Errorf("lack of number of args needs 4 but %d", len(args))
	}
	var nlri bgp.AddrPrefixInterface
	var ip net.IP
	iplen := 0

	mac, err := net.ParseMAC(args[0])
	if err != nil {
		return nil, nil, fmt.Errorf("invalid mac: %s", args[0])
	}
	if args[1] != "0.0.0.0" && args[1] != "::" {
		ip = net.ParseIP(args[1])
		if ip == nil {
			return nil, nil, fmt.Errorf("invalid ip prefix: %s", args[1])
		}
		iplen = net.IPv4len * 8
		if ip.To4() == nil {
			iplen = net.IPv6len * 8
		}
	}
	eTag, err := strconv.Atoi(args[2])
	if err != nil {
		return nil, nil, fmt.Errorf("invalid eTag: %s. err: %s", args[2], err)
	}
	label, err := strconv.Atoi(args[3])
	if err != nil {
		return nil, nil, fmt.Errorf("invalid label: %s. err: %s", args[3], err)
	}

	var rd bgp.RouteDistinguisherInterface
	if args[4] == "rd" && len(args) > 5 {
		rd, err = bgp.ParseRouteDistinguisher(args[5])
		if err != nil {
			return nil, nil, err
		}
	}

	macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
		RD: rd,
		ESI: bgp.EthernetSegmentIdentifier{
			Type: bgp.ESI_ARBITRARY,
		},
		MacAddressLength: 48,
		MacAddress:       mac,
		IPAddressLength:  uint8(iplen),
		IPAddress:        ip,
		Labels:           []uint32{uint32(label)},
		ETag:             uint32(eTag),
	}
	nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
	extcomms := args[6:]
	return nlri, extcomms, nil
}
Example #2
0
File: global.go Project: osrg/gobgp
func ParseEVPNIPPrefixArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
	if len(args) < 6 {
		return nil, nil, fmt.Errorf("lack of number of args needs 6 at least but got %d", len(args))
	}
	m := extractReserved(args, []string{"gw", "rd", "rt", "encap", "etag", "label"})
	if len(m[""]) < 1 {
		return nil, nil, fmt.Errorf("specify prefix")
	}
	ip, n, err := net.ParseCIDR(m[""][0])
	if err != nil {
		return nil, nil, err
	}
	ones, _ := n.Mask.Size()
	var gw net.IP
	if len(m["gw"]) > 0 {
		gw = net.ParseIP(m["gw"][0])
	}

	if len(m["rd"]) < 1 {
		return nil, nil, fmt.Errorf("specify RD")
	}
	rd, err := bgp.ParseRouteDistinguisher(m["rd"][0])
	if err != nil {
		return nil, nil, err
	}

	var etag uint32
	if len(m["etag"]) > 0 {
		e, err := strconv.Atoi(m["etag"][0])
		if err != nil {
			return nil, nil, err
		}
		etag = uint32(e)
	}

	var label uint32
	if len(m["label"]) > 0 {
		e, err := strconv.Atoi(m["label"][0])
		if err != nil {
			return nil, nil, err
		}
		label = uint32(e)
	}

	r := &bgp.EVPNIPPrefixRoute{
		RD:             rd,
		ETag:           etag,
		IPPrefixLength: uint8(ones),
		IPPrefix:       ip,
		GWIPAddress:    gw,
		Label:          label,
	}
	return bgp.NewEVPNNLRI(bgp.EVPN_IP_PREFIX, 0, r), nil, nil
}
Example #3
0
File: vrf.go Project: osrg/gobgp
func modVrf(typ string, args []string) error {
	var err error
	switch typ {
	case CMD_ADD:
		a := extractReserved(args, []string{"rd", "rt", "id"})
		if len(a[""]) != 1 || len(a["rd"]) != 1 || len(a["rt"]) < 2 || len(a["id"]) > 1 {
			return fmt.Errorf("Usage: gobgp vrf add <vrf name> [ id <id> ] rd <rd> rt { import | export | both } <rt>...")
		}
		name := a[""][0]
		rd, err := bgp.ParseRouteDistinguisher(a["rd"][0])
		if err != nil {
			return err
		}
		cur := ""
		importRt := make([]bgp.ExtendedCommunityInterface, 0)
		exportRt := make([]bgp.ExtendedCommunityInterface, 0)
		for _, elem := range a["rt"] {
			if elem == "import" || elem == "export" || elem == "both" {
				cur = elem
				continue
			}
			rt, err := bgp.ParseRouteTarget(elem)
			if err != nil {
				return err
			}
			switch cur {
			case "import":
				importRt = append(importRt, rt)
			case "export":
				exportRt = append(exportRt, rt)
			case "both":
				importRt = append(importRt, rt)
				exportRt = append(exportRt, rt)
			default:
				return fmt.Errorf("Usage: gobgp vrf add <vrf name> rd <rd> rt { import | export | both } <rt>...")
			}
		}
		vrfId := 0
		if len(a["id"]) > 0 {
			vrfId, err = strconv.Atoi(a["id"][0])
			if err != nil {
				return err
			}
		}
		err = client.AddVRF(name, vrfId, rd, importRt, exportRt)
	case CMD_DEL:
		if len(args) != 1 {
			return fmt.Errorf("Usage: gobgp vrf del <vrf name>")
		}
		err = client.DeleteVRF(args[0])
	}
	return err
}
Example #4
0
File: global.go Project: osrg/gobgp
func extractRouteDistinguisher(args []string) ([]string, bgp.RouteDistinguisherInterface, error) {
	for idx, arg := range args {
		if arg == "rd" {
			if len(args) < (idx + 1) {
				return nil, nil, fmt.Errorf("invalid rd format")
			}
			rd, err := bgp.ParseRouteDistinguisher(args[idx+1])
			if err != nil {
				return nil, nil, err
			}
			return append(args[:idx], args[idx+2:]...), rd, nil
		}
	}
	return args, nil, nil
}
Example #5
0
func ParseEvpnMulticastArgs(args []string) (bgp.AddrPrefixInterface, []string, error) {
	if len(args) < 2 {
		return nil, nil, fmt.Errorf("lack of number of args needs 2 but %d", len(args))
	}
	var nlri bgp.AddrPrefixInterface
	var ip net.IP
	iplen := 0

	if args[0] != "0.0.0.0" && args[0] != "::" {
		ip = net.ParseIP(args[0])
		if ip == nil {
			return nil, nil, fmt.Errorf("invalid ip prefix: %s", args[0])
		}
		iplen = net.IPv4len * 8
		if ip.To4() == nil {
			iplen = net.IPv6len * 8
		}
	}

	eTag, err := strconv.Atoi(args[1])
	if err != nil {
		return nil, nil, fmt.Errorf("invalid eTag: %s. err: %s", args[1], err)
	}

	var rd bgp.RouteDistinguisherInterface
	if args[2] == "rd" && len(args) > 3 {
		rd, err = bgp.ParseRouteDistinguisher(args[3])
		if err != nil {
			return nil, nil, err
		}
	}

	multicastEtag := &bgp.EVPNMulticastEthernetTagRoute{
		RD:              rd,
		IPAddressLength: uint8(iplen),
		IPAddress:       ip,
		ETag:            uint32(eTag),
	}
	extcomms := args[4:]
	nlri = bgp.NewEVPNNLRI(bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG, 0, multicastEtag)
	return nlri, extcomms, nil

}
Example #6
0
File: vrf.go Project: mfeed/gobgp
func modVrf(typ string, args []string) error {
	var err error
	switch typ {
	case CMD_ADD:
		if len(args) < 6 || args[1] != "rd" || args[3] != "rt" {
			return fmt.Errorf("Usage: gobgp vrf add <vrf name> rd <rd> rt { import | export | both } <rt>...")
		}
		name := args[0]
		rd, err := bgp.ParseRouteDistinguisher(args[2])
		if err != nil {
			return err
		}
		cur := ""
		importRt := make([][]byte, 0)
		exportRt := make([][]byte, 0)
		for _, elem := range args[4:] {
			if elem == "import" || elem == "export" || elem == "both" {
				cur = elem
				continue
			}
			rt, err := bgp.ParseRouteTarget(elem)
			if err != nil {
				return err
			}
			buf, err := rt.Serialize()
			if err != nil {
				return err
			}
			switch cur {
			case "import":
				importRt = append(importRt, buf)
			case "export":
				exportRt = append(exportRt, buf)
			case "both":
				importRt = append(importRt, buf)
				exportRt = append(exportRt, buf)
			default:
				return fmt.Errorf("Usage: gobgp vrf add <vrf name> rd <rd> rt { import | export | both } <rt>...")
			}
		}
		buf, _ := rd.Serialize()
		arg := &api.AddVrfRequest{
			Vrf: &api.Vrf{
				Name:     name,
				Rd:       buf,
				ImportRt: importRt,
				ExportRt: exportRt,
			},
		}
		_, err = client.AddVrf(context.Background(), arg)
	case CMD_DEL:
		if len(args) != 1 {
			return fmt.Errorf("Usage: gobgp vrf del <vrf name>")
		}
		arg := &api.DeleteVrfRequest{
			Vrf: &api.Vrf{
				Name: args[0],
			},
		}
		_, err = client.DeleteVrf(context.Background(), arg)
	}
	return err
}
Example #7
0
func ParsePath(rf bgp.RouteFamily, args []string) (*api.Path, error) {
	var nlri bgp.AddrPrefixInterface
	var extcomms []string
	var err error
	attrs := table.PathAttrs(make([]bgp.PathAttributeInterface, 0, 1))

	path := &api.Path{
		Pattrs: make([][]byte, 0),
	}

	fns := []func([]string) ([]string, bgp.PathAttributeInterface, error){
		extractOrigin,
		extractMed,
		extractLocalPref,
		extractCommunity,
		extractAigp,
	}

	for _, fn := range fns {
		var a bgp.PathAttributeInterface
		args, a, err = fn(args)
		if err != nil {
			return nil, err
		}
		if a != nil {
			attrs = append(attrs, a)
		}
	}

	args, nexthop, err := extractNexthop(rf, args)
	if err != nil {
		return nil, err
	}

	switch rf {
	case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
		if len(args) < 1 {
			return nil, fmt.Errorf("invalid format")
		}
		ip, net, err := net.ParseCIDR(args[0])
		if err != nil {
			return nil, err
		}
		ones, _ := net.Mask.Size()
		if rf == bgp.RF_IPv4_UC {
			if ip.To4() == nil {
				return nil, fmt.Errorf("invalid ipv4 prefix")
			}
			nlri = bgp.NewIPAddrPrefix(uint8(ones), ip.String())
		} else {
			if ip.To16() == nil {
				return nil, fmt.Errorf("invalid ipv6 prefix")
			}
			nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
		}

		extcomms = args[1:]

	case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN:
		if len(args) < 3 || args[1] != "rd" {
			return nil, fmt.Errorf("invalid format")
		}
		ip, net, _ := net.ParseCIDR(args[0])
		ones, _ := net.Mask.Size()

		rd, err := bgp.ParseRouteDistinguisher(args[2])
		if err != nil {
			return nil, err
		}

		extcomms = args[3:]

		mpls := bgp.NewMPLSLabelStack()

		if rf == bgp.RF_IPv4_VPN {
			if ip.To4() == nil {
				return nil, fmt.Errorf("invalid ipv4 prefix")
			}
			nlri = bgp.NewLabeledVPNIPAddrPrefix(uint8(ones), ip.String(), *mpls, rd)
		} else {
			if ip.To16() == nil {
				return nil, fmt.Errorf("invalid ipv6 prefix")
			}
			nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(ones), ip.String(), *mpls, rd)
		}
	case bgp.RF_IPv4_MPLS, bgp.RF_IPv6_MPLS:
		if len(args) < 2 {
			return nil, fmt.Errorf("invalid format")
		}

		ip, net, _ := net.ParseCIDR(args[0])
		ones, _ := net.Mask.Size()

		mpls, err := bgp.ParseMPLSLabelStack(args[1])
		if err != nil {
			return nil, err
		}

		extcomms = args[2:]

		if rf == bgp.RF_IPv4_MPLS {
			if ip.To4() == nil {
				return nil, fmt.Errorf("invalid ipv4 prefix")
			}
			nlri = bgp.NewLabeledIPAddrPrefix(uint8(ones), ip.String(), *mpls)
		} else {
			if ip.To4() != nil {
				return nil, fmt.Errorf("invalid ipv6 prefix")
			}
			nlri = bgp.NewLabeledIPv6AddrPrefix(uint8(ones), ip.String(), *mpls)
		}
	case bgp.RF_EVPN:
		nlri, extcomms, err = ParseEvpnArgs(args)
	case bgp.RF_FS_IPv4_UC, bgp.RF_FS_IPv6_UC, bgp.RF_FS_L2_VPN:
		nlri, extcomms, err = ParseFlowSpecArgs(rf, args)
	case bgp.RF_OPAQUE:
		m := extractReserved(args, []string{"key", "value"})
		if len(m["key"]) != 1 || len(m["value"]) != 1 {
			return nil, fmt.Errorf("invalid key-value format")
		}
		nlri = bgp.NewOpaqueNLRI([]byte(m["key"][0]))
		attrs = append(attrs, bgp.NewPathAttributeOpaqueValue([]byte(m["value"][0])))
	default:
		return nil, fmt.Errorf("Unsupported route family: %s", rf)
	}
	if err != nil {
		return nil, err
	}

	if rf == bgp.RF_IPv4_UC {
		path.Nlri, _ = nlri.Serialize()
		attrs = append(attrs, bgp.NewPathAttributeNextHop(nexthop))
	} else {
		mpreach := bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri})
		attrs = append(attrs, mpreach)
	}

	if extcomms != nil && len(extcomms) > 0 {
		extcomms, err := ParseExtendedCommunities(strings.Join(extcomms, " "))
		if err != nil {
			return nil, err
		}
		p := bgp.NewPathAttributeExtendedCommunities(extcomms)
		attrs = append(attrs, p)
	}

	sort.Sort(attrs)

	for _, attr := range attrs {
		buf, err := attr.Serialize()
		if err != nil {
			return nil, err
		}
		path.Pattrs = append(path.Pattrs, buf)
	}
	return path, nil
}
Example #8
0
File: global.go Project: osrg/gobgp
func ParsePath(rf bgp.RouteFamily, args []string) (*table.Path, error) {
	var nlri bgp.AddrPrefixInterface
	var rd bgp.RouteDistinguisherInterface
	var extcomms []string
	var err error
	attrs := table.PathAttrs(make([]bgp.PathAttributeInterface, 0, 1))

	fns := []func([]string) ([]string, bgp.PathAttributeInterface, error){
		extractOrigin,
		extractMed,
		extractLocalPref,
		extractCommunity,
		extractAigp,
		extractAggregator,
		extractLargeCommunity,
	}

	for _, fn := range fns {
		var a bgp.PathAttributeInterface
		args, a, err = fn(args)
		if err != nil {
			return nil, err
		}
		if a != nil {
			attrs = append(attrs, a)
		}
	}

	args, nexthop, err := extractNexthop(rf, args)
	if err != nil {
		return nil, err
	}

	switch rf {
	case bgp.RF_IPv4_UC, bgp.RF_IPv6_UC:
		if len(args) < 1 {
			return nil, fmt.Errorf("invalid format")
		}
		ip, net, err := net.ParseCIDR(args[0])
		if err != nil {
			return nil, err
		}
		ones, _ := net.Mask.Size()
		if rf == bgp.RF_IPv4_UC {
			if ip.To4() == nil {
				return nil, fmt.Errorf("invalid ipv4 prefix")
			}
			nlri = bgp.NewIPAddrPrefix(uint8(ones), ip.String())
		} else {
			if ip.To16() == nil {
				return nil, fmt.Errorf("invalid ipv6 prefix")
			}
			nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
		}

		extcomms = args[1:]

	case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN:
		if len(args) < 5 || args[1] != "label" || args[3] != "rd" {
			return nil, fmt.Errorf("invalid format")
		}
		ip, net, _ := net.ParseCIDR(args[0])
		ones, _ := net.Mask.Size()

		label := 0
		if label, err = strconv.Atoi(args[2]); err != nil {
			return nil, fmt.Errorf("invalid format")
		}
		mpls := bgp.NewMPLSLabelStack(uint32(label))

		rd, err = bgp.ParseRouteDistinguisher(args[4])
		if err != nil {
			return nil, err
		}

		extcomms = args[5:]

		if rf == bgp.RF_IPv4_VPN {
			if ip.To4() == nil {
				return nil, fmt.Errorf("invalid ipv4 prefix")
			}
			nlri = bgp.NewLabeledVPNIPAddrPrefix(uint8(ones), ip.String(), *mpls, rd)
		} else {
			if ip.To16() == nil {
				return nil, fmt.Errorf("invalid ipv6 prefix")
			}
			nlri = bgp.NewLabeledVPNIPv6AddrPrefix(uint8(ones), ip.String(), *mpls, rd)
		}
	case bgp.RF_IPv4_MPLS, bgp.RF_IPv6_MPLS:
		if len(args) < 2 {
			return nil, fmt.Errorf("invalid format")
		}

		ip, net, _ := net.ParseCIDR(args[0])
		ones, _ := net.Mask.Size()

		mpls, err := bgp.ParseMPLSLabelStack(args[1])
		if err != nil {
			return nil, err
		}

		extcomms = args[2:]

		if rf == bgp.RF_IPv4_MPLS {
			if ip.To4() == nil {
				return nil, fmt.Errorf("invalid ipv4 prefix")
			}
			nlri = bgp.NewLabeledIPAddrPrefix(uint8(ones), ip.String(), *mpls)
		} else {
			if ip.To4() != nil {
				return nil, fmt.Errorf("invalid ipv6 prefix")
			}
			nlri = bgp.NewLabeledIPv6AddrPrefix(uint8(ones), ip.String(), *mpls)
		}
	case bgp.RF_EVPN:
		nlri, extcomms, err = ParseEvpnArgs(args)
	case bgp.RF_FS_IPv4_VPN, bgp.RF_FS_IPv6_VPN, bgp.RF_FS_L2_VPN:
		args, rd, err = extractRouteDistinguisher(args)
		if err != nil {
			return nil, err
		}
		fallthrough
	case bgp.RF_FS_IPv4_UC, bgp.RF_FS_IPv6_UC:
		nlri, extcomms, err = ParseFlowSpecArgs(rf, args, rd)
	case bgp.RF_OPAQUE:
		m := extractReserved(args, []string{"key", "value"})
		if len(m["key"]) != 1 {
			return nil, fmt.Errorf("opaque nlri key missing")
		}
		if len(m["value"]) > 0 {
			nlri = bgp.NewOpaqueNLRI([]byte(m["key"][0]), []byte(m["value"][0]))
		} else {
			nlri = bgp.NewOpaqueNLRI([]byte(m["key"][0]), nil)
		}
	default:
		return nil, fmt.Errorf("Unsupported route family: %s", rf)
	}
	if err != nil {
		return nil, err
	}

	if rf == bgp.RF_IPv4_UC {
		attrs = append(attrs, bgp.NewPathAttributeNextHop(nexthop))
	} else {
		mpreach := bgp.NewPathAttributeMpReachNLRI(nexthop, []bgp.AddrPrefixInterface{nlri})
		attrs = append(attrs, mpreach)
	}

	if extcomms != nil && len(extcomms) > 0 {
		extcomms, err := ParseExtendedCommunities(strings.Join(extcomms, " "))
		if err != nil {
			return nil, err
		}
		p := bgp.NewPathAttributeExtendedCommunities(extcomms)
		attrs = append(attrs, p)
	}

	sort.Sort(attrs)

	return table.NewPath(nil, nlri, false, attrs, time.Now(), false), nil
}