summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gobgp/global.go52
-rw-r--r--packet/bgp.go26
2 files changed, 55 insertions, 23 deletions
diff --git a/gobgp/global.go b/gobgp/global.go
index 9c272691..1ea62ddb 100644
--- a/gobgp/global.go
+++ b/gobgp/global.go
@@ -31,22 +31,16 @@ func showGlobalRib(args []string) error {
return showNeighborRib(CMD_GLOBAL, bogusIp, args)
}
-func parseRD(args []string) (*api.RouteDistinguisher, error) {
- t, err := strconv.Atoi(args[0])
- if err != nil {
- return nil, err
- }
- typ := api.ROUTE_DISTINGUISHER_TYPE(t)
- admin := args[1]
- assigned, err := strconv.Atoi(args[2])
- if err != nil {
- return nil, err
+func getSerizliedRouteTarget(args []string) ([]byte, error) {
+ rts := make([]bgp.ExtendedCommunityInterface, 0, len(args))
+ for _, elem := range args {
+ rt, err := bgp.ParseRouteTarget(elem)
+ if err != nil {
+ return nil, err
+ }
+ rts = append(rts, rt)
}
- return &api.RouteDistinguisher{
- Type: typ,
- Admin: admin,
- Assigned: uint32(assigned),
- }, nil
+ return bgp.NewPathAttributeExtendedCommunities(rts).Serialize()
}
func modPath(modtype string, args []string) error {
@@ -57,6 +51,7 @@ func modPath(modtype string, args []string) error {
var nlri bgp.AddrPrefixInterface
var nexthop string
+ var rts []string
switch rf {
case api.AF_IPV4_UC, api.AF_IPV6_UC:
@@ -80,8 +75,8 @@ func modPath(modtype string, args []string) error {
nlri = bgp.NewIPv6AddrPrefix(uint8(ones), ip.String())
}
case api.AF_IPV4_VPN, api.AF_IPV6_VPN:
- if len(args) < 3 || args[1] != "rd" {
- return fmt.Errorf("usage: global rib %s <prefix> rd <rd> -a { vpn-ipv4 | vpn-ipv6 }", modtype)
+ if len(args) < 3 || args[1] != "rd" || args[3] != "rt" {
+ return fmt.Errorf("usage: global rib %s <prefix> rd <rd> rt <rt>... -a { vpn-ipv4 | vpn-ipv6 }", modtype)
}
ip, net, _ := net.ParseCIDR(args[0])
ones, _ := net.Mask.Size()
@@ -91,6 +86,8 @@ func modPath(modtype string, args []string) error {
return err
}
+ rts = args[4:]
+
mpls := bgp.NewMPLSLabelStack()
if rf == api.AF_IPV4_VPN {
@@ -116,8 +113,8 @@ func modPath(modtype string, args []string) error {
switch subtype {
case "macadv":
- if len(args) < 6 || args[4] != "rd" {
- return fmt.Errorf("usage: global rib %s macadv <mac address> <ip address> <etag> <label> rd <rd> -a evpn", modtype)
+ if len(args) < 6 || args[4] != "rd" || args[6] != "rt" {
+ return fmt.Errorf("usage: global rib %s macadv <mac address> <ip address> <etag> <label> rd <rd> rt <rt>... -a evpn", modtype)
}
mac, err := net.ParseMAC(args[0])
if err != nil {
@@ -147,6 +144,9 @@ func modPath(modtype string, args []string) error {
if err != nil {
return err
}
+
+ rts = args[7:]
+
macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{
RD: rd,
ESI: bgp.EthernetSegmentIdentifier{
@@ -161,8 +161,8 @@ func modPath(modtype string, args []string) error {
}
nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv)
case "multicast":
- if len(args) < 5 || args[2] != "rd" {
- return fmt.Errorf("usage : global rib %s multicast <ip address> <etag> rd <rd> -a evpn", modtype)
+ if len(args) < 5 || args[2] != "rd" || args[4] != "rt" {
+ return fmt.Errorf("usage : global rib %s multicast <ip address> <etag> rd <rd> rt <rt> -a evpn", modtype)
}
var ip net.IP
@@ -188,6 +188,8 @@ func modPath(modtype string, args []string) error {
return err
}
+ rts = args[5:]
+
multicastEtag := &bgp.EVPNMulticastEthernetTagRoute{
RD: rd,
IPAddressLength: uint8(iplen),
@@ -227,6 +229,14 @@ func modPath(modtype string, args []string) error {
origin, _ := bgp.NewPathAttributeOrigin(bgp.BGP_ORIGIN_ATTR_TYPE_IGP).Serialize()
arg.RawPattrs = append(arg.RawPattrs, origin)
+ if rts != nil && len(rts) > 0 {
+ extcomm, err := getSerizliedRouteTarget(rts)
+ if err != nil {
+ return err
+ }
+ arg.RawPattrs = append(arg.RawPattrs, extcomm)
+ }
+
stream, err := client.ModPath(context.Background())
if err != nil {
return err
diff --git a/packet/bgp.go b/packet/bgp.go
index 35e70e72..31dde01f 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -860,7 +860,7 @@ func getRouteDistinguisher(data []byte) RouteDistinguisherInterface {
return rd
}
-func parseRd(input string) ([]string, error) {
+func parseRdAndRt(input string) ([]string, error) {
exp := regexp.MustCompile("^((\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)|((\\d+)\\.)?(\\d+)):(\\d+)$")
group := exp.FindSubmatch([]byte(input))
if len(group) != 10 {
@@ -874,7 +874,7 @@ func parseRd(input string) ([]string, error) {
}
func ParseRouteDistinguisher(rd string) (RouteDistinguisherInterface, error) {
- elems, err := parseRd(rd)
+ elems, err := parseRdAndRt(rd)
if err != nil {
return nil, err
}
@@ -3235,6 +3235,28 @@ func NewFourOctetAsSpecificExtended(as uint32, localAdmin uint16, isTransitive b
}
}
+func ParseRouteTarget(rt string) (ExtendedCommunityInterface, error) {
+ elems, err := parseRdAndRt(rt)
+ if err != nil {
+ return nil, err
+ }
+ localAdmin, _ := strconv.Atoi(elems[9])
+ ip := net.ParseIP(elems[1])
+ isTransitive := true
+ switch {
+ case ip.To4() != nil:
+ return NewIPv4AddressSpecificExtended(elems[1], uint16(localAdmin), isTransitive), nil
+ case elems[6] == "" && elems[7] == "":
+ asn, _ := strconv.Atoi(elems[8])
+ return NewTwoOctetAsSpecificExtended(uint16(asn), uint32(localAdmin), isTransitive), nil
+ default:
+ fst, _ := strconv.Atoi(elems[7])
+ snd, _ := strconv.Atoi(elems[8])
+ asn := fst<<16 | snd
+ return NewFourOctetAsSpecificExtended(uint32(asn), uint16(localAdmin), isTransitive), nil
+ }
+}
+
type OpaqueExtendedValueInterface interface {
Serialize() ([]byte, error)
String() string