func (p *Path) ToGlobal(vrf *Vrf) *Path { nlri := p.GetNlri() nh := p.GetNexthop() switch rf := p.GetRouteFamily(); rf { case bgp.RF_IPv4_UC: n := nlri.(*bgp.IPAddrPrefix) nlri = bgp.NewLabeledVPNIPAddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), vrf.Rd) case bgp.RF_IPv6_UC: n := nlri.(*bgp.IPv6AddrPrefix) nlri = bgp.NewLabeledVPNIPv6AddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), vrf.Rd) case bgp.RF_EVPN: n := nlri.(*bgp.EVPNNLRI) switch n.RouteType { case bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT: old := n.RouteTypeData.(*bgp.EVPNMacIPAdvertisementRoute) new := &bgp.EVPNMacIPAdvertisementRoute{ RD: vrf.Rd, ESI: old.ESI, ETag: old.ETag, MacAddressLength: old.MacAddressLength, MacAddress: old.MacAddress, IPAddressLength: old.IPAddressLength, IPAddress: old.IPAddress, Labels: old.Labels, } nlri = bgp.NewEVPNNLRI(n.RouteType, n.Length, new) case bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG: old := n.RouteTypeData.(*bgp.EVPNMulticastEthernetTagRoute) new := &bgp.EVPNMulticastEthernetTagRoute{ RD: vrf.Rd, ETag: old.ETag, IPAddressLength: old.IPAddressLength, IPAddress: old.IPAddress, } nlri = bgp.NewEVPNNLRI(n.RouteType, n.Length, new) } default: return p } path := NewPath(p.OriginInfo().source, nlri, p.IsWithdraw, p.GetPathAttrs(), p.OriginInfo().timestamp, false) path.SetExtCommunities(vrf.ExportRt, false) path.delPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP) path.setPathAttr(bgp.NewPathAttributeMpReachNLRI(nh.String(), []bgp.AddrPrefixInterface{nlri})) return path }
func (v *Vrf) ToGlobalPath(path *Path) error { nlri := path.GetNlri() switch rf := path.GetRouteFamily(); rf { case bgp.RF_IPv4_UC: n := nlri.(*bgp.IPAddrPrefix) path.OriginInfo().nlri = bgp.NewLabeledVPNIPAddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), v.Rd) case bgp.RF_IPv6_UC: n := nlri.(*bgp.IPv6AddrPrefix) path.OriginInfo().nlri = bgp.NewLabeledVPNIPv6AddrPrefix(n.Length, n.Prefix.String(), *bgp.NewMPLSLabelStack(0), v.Rd) case bgp.RF_EVPN: n := nlri.(*bgp.EVPNNLRI) switch n.RouteType { case bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT: n.RouteTypeData.(*bgp.EVPNMacIPAdvertisementRoute).RD = v.Rd case bgp.EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG: n.RouteTypeData.(*bgp.EVPNMulticastEthernetTagRoute).RD = v.Rd } default: return fmt.Errorf("unsupported route family for vrf: %s", rf) } path.SetExtCommunities(v.ExportRt, false) return nil }
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 }
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 }