Skip to content

Commit

Permalink
change all "next-hop self" to be IP
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-mangin committed Mar 29, 2023
1 parent 583d473 commit e68e8a8
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 21 deletions.
6 changes: 5 additions & 1 deletion etc/exabgp/api-nexthop-self.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ neighbor 127.0.0.1 {
processes [ announce-routes ];
}
static {
route 10.0.0.1 next-hop self;
route 10.0.0.2 {
next-hop self;
}
}
announce {
ipv4 {
unicast 10.0.0.1 next-hop self;
}
}
}
12 changes: 1 addition & 11 deletions lib/exabgp/bgp/message/open/capability/negotiated.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,17 +172,7 @@ def validate(self, neighbor):
return None

def nexthopself(self, afi):
if afi == self.neighbor.local_address.afi:
return self.neighbor.local_address

# attempting to not barf for next-hop self when the peer is IPv6
if afi == AFI.ipv4:
return self.neighbor.router_id

raise TypeError(
'use of "next-hop self": the route (%s) does not have the same family as the BGP tcp session (%s)'
% (afi, self.neighbor.local_address.afi)
)
return self.neighbor.ip_self(afi)


# =================================================================== RequirePath
Expand Down
27 changes: 25 additions & 2 deletions lib/exabgp/bgp/neighbor.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
from exabgp.protocol.family import AFI

from exabgp.bgp.message import Message
from exabgp.bgp.message.open.capability import NextHop
from exabgp.bgp.message.open.capability import AddPath
from exabgp.bgp.message.update.attribute import NextHop
from exabgp.bgp.message.update.attribute import Attribute

from exabgp.rib import RIB

Expand Down Expand Up @@ -405,5 +405,28 @@ def string(self, with_changes=True):
# '\t\tsend {\n%s\t\t}\n' % send if send else '',
return returned.replace('\t', ' ')

def ip_self(self, afi):
if afi == self.local_address.afi:
return self.local_address

# attempting to not barf for next-hop self when the peer is IPv6
if afi == AFI.ipv4:
return self.router_id

raise TypeError(
'use of "next-hop self": the route (%s) does not have the same family as the BGP tcp session (%s)'
% (afi, self.local_address.afi)
)

# NOTE: this may very well modify the change object passed to the function
def remove_self(self, change):
if not change.nlri.nexthop.SELF:
return change
neighbor_self = self.ip_self(change.nlri.afi)
change.nlri.nexthop = neighbor_self
if Attribute.CODE.NEXT_HOP in change.attributes:
change.attributes[Attribute.CODE.NEXT_HOP] = NextHop(str(neighbor_self),neighbor_self.pack())
return change

def __str__(self):
return self.string(False)
9 changes: 5 additions & 4 deletions lib/exabgp/configuration/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ def __init__(self):

def inject_change(self, peers, change):
result = True
for neighbor in self.neighbors:
if neighbor in peers:
if change.nlri.family() in self.neighbors[neighbor].families():
self.neighbors[neighbor].rib.outgoing.add_to_rib(change)
for neighbor_name in self.neighbors:
if neighbor_name in peers:
neighbor = self.neighbors[neighbor_name]
if change.nlri.family() in neighbor.families():
neighbor.rib.outgoing.add_to_rib(neighbor.remove_self(change))
else:
self.logger.error('the route family is not configured on neighbor', 'configuration')
result = False
Expand Down
10 changes: 7 additions & 3 deletions lib/exabgp/configuration/neighbor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,19 +246,23 @@ def post(self):
neighbor.add_nexthop(afi, safi, nhafi)

neighbor.changes = []
neighbor.changes.extend(self.scope.pop_routes())
for change in self.scope.pop_routes():
# remove_self may well have side effects on change
neighbor.changes.append(neighbor.remove_self(change))

# old format
for section in ('static', 'l2vpn', 'flow'):
routes = local.get(section, {}).get('routes', [])
for route in routes:
route.nlri.action = OUT.ANNOUNCE
neighbor.changes.extend(routes)
# remove_self may well have side effects on change
neighbor.changes.append(neighbor.remove_self(route))

routes = local.get('routes', [])
for route in routes:
route.nlri.action = OUT.ANNOUNCE
neighbor.changes.extend(routes)
# remove_self may well have side effects on change
neighbor.changes.append(neighbor.remove_self(route))

messages = local.get('operational', {}).get('routes', [])

Expand Down
6 changes: 6 additions & 0 deletions lib/exabgp/protocol/ip/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@


class IPSelf(object):
SELF = True

def __init__(self, afi):
self.afi = afi

Expand All @@ -45,6 +47,8 @@ def index(self):


class IP(object):
SELF = False

afi = None # here for the API, changed in init which does not change this
_known = dict()

Expand Down Expand Up @@ -214,6 +218,8 @@ def __repr__(self):


class _NoNextHop(object):
SELF = False

packed = ''

def pack(self, data, negotiated=None):
Expand Down

0 comments on commit e68e8a8

Please sign in to comment.