diff options
-rw-r--r-- | gobgp/main.go | 13 | ||||
-rw-r--r-- | server/peer.go | 41 |
2 files changed, 51 insertions, 3 deletions
diff --git a/gobgp/main.go b/gobgp/main.go index a433d181..fcc16b17 100644 --- a/gobgp/main.go +++ b/gobgp/main.go @@ -598,6 +598,8 @@ func (x *PathCommand) Execute(args []string) error { rt = api.AF_IPV4_UC case "ipv6", "v6", "6": rt = api.AF_IPV6_UC + case "evpn": + rt = api.AF_EVPN default: return fmt.Errorf("unsupported address family: %s", args[1]) } @@ -610,6 +612,17 @@ func (x *PathCommand) Execute(args []string) error { Af: rt, Prefix: args[2], } + case api.AF_EVPN: + path.Nlri = &api.Nlri{ + Af: rt, + EvpnNlri: &api.EVPNNlri{ + Type: api.EVPN_TYPE_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, + MacIpAdv: &api.EvpnMacIpAdvertisement{ + MacAddr: args[2], + IpAddr: args[3], + }, + }, + } } switch x.modtype { diff --git a/server/peer.go b/server/peer.go index 2570019f..142c801d 100644 --- a/server/peer.go +++ b/server/peer.go @@ -311,7 +311,8 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) { asparam := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint32{peer.peerInfo.AS}) pattr = append(pattr, bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{asparam})) - if rf == bgp.RF_IPv4_UC { + switch rf { + case bgp.RF_IPv4_UC: ip, net, _ := net.ParseCIDR(path.Nlri.Prefix) if ip.To4() == nil { result.ResponseErr = fmt.Errorf("Invalid ipv4 prefix: %s", path.Nlri.Prefix) @@ -326,7 +327,8 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) { pattr = append(pattr, bgp.NewPathAttributeNextHop("0.0.0.0")) - } else if rf == bgp.RF_IPv6_UC { + case bgp.RF_IPv6_UC: + ip, net, _ := net.ParseCIDR(path.Nlri.Prefix) if ip.To16() == nil { result.ResponseErr = fmt.Errorf("Invalid ipv6 prefix: %s", path.Nlri.Prefix) @@ -339,7 +341,40 @@ func (peer *Peer) handleGrpc(grpcReq *GrpcRequest) { pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("::", []bgp.AddrPrefixInterface{nlri})) - } else { + case bgp.RF_EVPN: + mac, err := net.ParseMAC(path.Nlri.EvpnNlri.MacIpAdv.MacAddr) + if err != nil { + result.ResponseErr = fmt.Errorf("Invalid mac: %s", path.Nlri.EvpnNlri.MacIpAdv.MacAddr) + grpcReq.ResponseCh <- result + close(grpcReq.ResponseCh) + return + } + ip := net.ParseIP(path.Nlri.EvpnNlri.MacIpAdv.IpAddr) + if ip == nil { + result.ResponseErr = fmt.Errorf("Invalid ip prefix: %s", path.Nlri.EvpnNlri.MacIpAdv.IpAddr) + grpcReq.ResponseCh <- result + close(grpcReq.ResponseCh) + return + } + iplen := net.IPv4len * 8 + if ip.To4() == nil { + iplen = net.IPv6len * 8 + } + + macIpAdv := &bgp.EVPNMacIPAdvertisementRoute{ + RD: bgp.NewRouteDistinguisherTwoOctetAS(0, 0), + ESI: bgp.EthernetSegmentIdentifier{ + Type: bgp.ESI_ARBITRARY, + }, + MacAddressLength: 48, + MacAddress: mac, + IPAddressLength: uint8(iplen), + IPAddress: ip, + Labels: []uint32{0}, + } + nlri = bgp.NewEVPNNLRI(bgp.EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, 0, macIpAdv) + pattr = append(pattr, bgp.NewPathAttributeMpReachNLRI("0.0.0.0", []bgp.AddrPrefixInterface{nlri})) + default: result.ResponseErr = fmt.Errorf("Unsupported address family: %s", rf) grpcReq.ResponseCh <- result close(grpcReq.ResponseCh) |