Ejemplo n.º 1
0
Archivo: global.go Proyecto: 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
}
Ejemplo n.º 2
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
}
Ejemplo n.º 3
0
//AddLocalProtoRoute is used to add local endpoint to the protocol RIB
func (self *OfnetBgp) AddLocalProtoRoute(pathInfo *OfnetProtoRouteInfo) error {
	log.Infof("Received AddLocalProtoRoute to add local endpoint to protocol RIB: %v", pathInfo)
	if self.routerIP == "" {
		//ignoring populating to the bgp rib because
		//Bgp is not configured.
		return nil
	}

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

	aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{self.myBgpAs})}
	aspath, _ := bgp.NewPathAttributeAsPath(aspathParam).Serialize()
	path.Pattrs = append(path.Pattrs, aspath)

	// form the path structure with appropriate path attributes
	nlri := bgp.NewIPAddrPrefix(32, pathInfo.localEpIP)
	path.Nlri, _ = nlri.Serialize()
	origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_EGP).Serialize()
	path.Pattrs = append(path.Pattrs, origin)
	log.Infof("Received AddLocalProtoRoute aspath: %v", aspath)
	mpls, err := bgp.ParseMPLSLabelStack("3")
	if err != nil {
		return nil
	}
	var nlri2 bgp.AddrPrefixInterface
	nlri2 = bgp.NewLabeledIPAddrPrefix(32, pathInfo.localEpIP, *mpls)
	mpreach, _ := bgp.NewPathAttributeMpReachNLRI(pathInfo.nextHopIP, []bgp.AddrPrefixInterface{nlri2}).Serialize()
	log.Infof("Received AddLocalProtoRoute nlri2: %v, mpreach: %v", nlri2, mpreach)
	path.Pattrs = append(path.Pattrs, mpreach)
	//path.Pattrs = append(path.Pattrs, n)

	arg := &api.AddPathRequest{
		Resource: api.Resource_GLOBAL,
		VrfId:    "default",
		Path:     path,
	}
	log.Infof("BGP - arg %v ", arg)
	// add routes
	/*
	   	prefix := pathInfo.localEpIP
	   	log.Infof("BGP - Prefix %v " , prefix )
	       	path2, err := cmd.ParsePath(bgp.RF_IPv4_MPLS, []string{"10.200.1.25/32", "3"})
	   	log.Infof("BGP - Path2 %v " , path2 )
	   	log.Infof("BGP - Err %v " , err )
	       	req := bgpserver.NewGrpcRequest(bgpserver.REQ_ADD_PATH, "", bgp.RouteFamily(0), &api.AddPathRequest{
	           	Resource: api.Resource_GLOBAL,
	           	Path:     path2,
	       	})
	       	self.bgpServer.GrpcReqCh <- req
	       	res := <-req.ResponseCh
	       	if err := res.Err(); err != nil {
	           	log.Fatal(err)
	   		log.Infof("BGP - Err %v " , err)
	       	}
	*/
	//send arguement stream
	client := api.NewGobgpApiClient(self.cc)
	if client == nil {
		log.Infof("Gobgpapi stream invalid")
		return nil
	}
	stream, err := client.AddPath(context.Background(), arg)
	if err != nil {
		log.Infof("Fail to enforce Modpath: %v %v", err, stream)
		return err
	}

	return nil
}