[quagga-dev 16619] Re: Quagga NHRPD / Cisco IOS 15.5(2)T

Patrick Oeschger patrick.oeschger at bluewin.ch
Mon May 22 07:21:32 BST 2017


Hi
Patch tested - looks better but there seems to remain a 'route inject'
issue on the spoke router (Cisco IOS).

NHRP Cache on hub:
quagga-router# sh ip nhrp cache
Iface    Type     Protocol                 NBMA                    
Flags  Identity
tun1     local    10.0.0.1                 -                               -
tun1     dynamic  10.0.0.3                 178.197.232.6           
UT     192.168.8.100
tun1     dynamic  10.0.0.2                 194.209.75.35           
UT     194.209.75.35
tun1     dynamic  10.0.0.4                 194.209.75.37           
UT     194.209.75.37  *** rem: cisco device ***

Registration for Cisco router (194.209.75.37) works fine :)

Ping to 10.0.0.4 is encapsulated correctly on hub ...

$ sudo tcpdump -i tun1 -n -c10 host 10.0.0.4
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun1, link-type LINUX_SLL (Linux cooked), capture size
262144 bytes
07:54:10.997424 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 14763, seq
1, length 64
07:54:11.997530 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 14763, seq
2, length 64

$ sudo tcpdump -i ens160 -n -c10 host 194.209.75.37
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), capture size 262144 bytes
07:55:07.637959 IP 217.193.211.21 > 194.209.75.37:
ESP(spi=0x84308476,seq=0xd), length 136
07:55:08.637647 IP 217.193.211.21 > 194.209.75.37:
ESP(spi=0x84308476,seq=0xe), length 136

IPSec SA up and running

dmvpn: #154, ESTABLISHED, IKEv1, ca7cf85e9433ee25_i f2ed204c5f9e2296_r*
  local  '217.193.211.21' @ 217.193.211.21[500]
  remote '194.209.75.37' @ 194.209.75.37[500]
  AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
  established 370s ago, reauth in 45770s
  dmvpn: #992, reqid 28, INSTALLED, TRANSPORT,
ESP:AES_CBC-256/HMAC_SHA2_256_128
    installed 370s ago, rekeying in 3072s, expires in 3590s
    in  c638adaa,     96 bytes,     1 packets,   370s ago
    out 1caf43f8,    644 bytes,     7 packets,     2s ago
    local  217.193.211.21/32[gre]
    remote 194.209.75.37/32[gre]

routing OK as well on hub side ...

$ ip route list
default via 217.193.211.17 dev ens160 onlink
10.0.0.2 dev tun1  proto zebra  scope link  metric 20
10.0.0.3 dev tun1  proto zebra  scope link  metric 20
10.0.0.4 dev tun1  proto zebra  scope link  metric 20
192.168.40.0/24 via 10.0.0.3 dev tun1  proto zebra  metric 20
217.193.211.16/28 dev ens160  proto kernel  scope link  src 217.193.211.21

debug log on Cisco router

*May 22 06:06:24.681: NHRP: Setting retrans delay to 1 for nhs  dst 10.0.0.1
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:0
*May 22 06:06:24.681: NHRP-MPLS: Could not find AVL node for tableid: 0
vrf:
*May 22 06:06:24.681: NHRP: Attempting to send packet through interface
Tunnel10 via DEST  dst 10.0.0.4
*May 22 06:06:24.681: NHRP: Send Registration Request via Tunnel10 vrf
0, packet size: 92
*May 22 06:06:24.681:       src: 10.0.0.4, dst: 10.0.0.4
*May 22 06:06:24.681: NHRP: Switching directly using pre-set NBMA
217.193.211.21
*May 22 06:06:24.681: NHRP: Encapsulation succeeded.  Sending NHRP
Control Packet  NBMA Address: 217.193.211.21
*May 22 06:06:24.681: NHRP: 116 bytes out Tunnel10
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32771, ext_len : 20
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32772, ext_len : 0
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32773, ext_len : 0
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 9, ext_len : 20
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32768, ext_len : 0
*May 22 06:06:24.681: NHRP: Receive Registration Reply via Tunnel10 vrf
0, packet size: 112
*May 22 06:06:24.681: NHRP: netid_in = 0, to_us = 1
*May 22 06:06:24.681: NHRP: No NHRP subblock found in packet
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:0
*May 22 06:06:24.681: NHRP-MPLS: Could not find AVL node for tableid: 0
vrf:
*May 22 06:06:24.681: NHRP: Enqueued static mapping to start of list
*May 22 06:06:24.681: NHRP: Tu10: Creating nhs  mapping  for 10.0.0.1/32
NBMA: 217.193.211.21
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:0
*May 22 06:06:24.681: NHRP-MPLS: Could not find AVL node for tableid: 0
vrf:
*May 22 06:06:24.681: NHRP: NHRP AVL root is NULL
*May 22 06:06:24.681: NHRP-MPLS: Inserted AVL node tableid: 0 vrf:
*May 22 06:06:24.681: NHRP-MPLS: Success: initialized cache radix tree
head tableid: 0 vrf:
*May 22 06:06:24.681: NHRP: Attempting to create instance PDB for (0x0)
*May 22 06:06:24.681: NHRP: Initialized cache with AVL root:2C69D948
*May 22 06:06:24.681: NHRP: swidb Tunnel10, nhrp_cache_update
*May 22 06:06:24.681: NHRP-MPLS:  tableid: 0 vrf:
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.681: NHRP: Tunnel10: Cache add for target 10.0.0.1/32
next-hop 10.0.0.1
*May 22 06:06:24.681:            217.193.211.21
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.681: NHRP: Adding Tunnel Endpoints (VPN: 10.0.0.1,
NBMA: 217.193.211.21)
*May 22 06:06:24.685: NHRP: Successfully attached NHRP subblock for
Tunnel Endpoints (VPN: 10.0.0.1, NBMA: 217.193.211.21)
*May 22 06:06:24.685: NHRP: No peer data updated in NHRP subblock for
Tunnel Endpoints (VPN: 10.0.0.1, NBMA: 217.193.211.21)
*May 22 06:06:24.685: NHRP: Inserted subblock node for cache: Target
10.0.0.1/32 nhop 10.0.0.1
*May 22 06:06:24.685: NHRP: Converted internal static cache entry for
10.0.0.1/32 interface Tunnel10 to external
*May 22 06:06:24.685: NHRP-MPLS:  tableid: 0 vrf:
*May 22 06:06:24.685: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.685: NHRP: NHS-UP: 10.0.0.1
*May 22 06:06:24.685: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.685: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.685: NHRP: Updating our cache with NBMA:
217.193.211.21, NBMA_ALT: 194.209.75.37

NHRP route on Cisco router seems to be missing...

#sh ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static
route
       o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
       a - application route
       + - replicated route, % - next hop override

Gateway of last resort is 194.209.75.33 to network 0.0.0.0

S*    0.0.0.0/0 [1/0] via 194.209.75.33
      10.0.0.0/32 is subnetted, 1 subnets
C        10.0.0.4 is directly connected, Tunnel10
      194.209.75.0/24 is variably subnetted, 2 subnets, 2 masks
C        194.209.75.32/28 is directly connected, GigabitEthernet0/0
L        194.209.75.37/32 is directly connected, GigabitEthernet0/0

my 2cents ...
/pat


On 03.05.2017 07:46, Timo Teras wrote:
> Hi,
>
> Can you test the patch in the end of the mail.
>
> Thanks,
> Timo
>
> On Wed, 3 May 2017 06:32:35 +0200
> Patrick Oeschger <patrick.oeschger at bluewin.ch> wrote:
>
>> thanks for your reply
>> sample cisco nhrp capture in attachment
>> first two packets are cisco - second two packets are quagga
>>
>> On 01.05.2017 07:39, Timo Teras wrote:
>>> Hi,
>>>
>>> On Mon, 1 May 2017 07:21:26 +0200
>>> Patrick Oeschger <patrick.oeschger at bluewin.ch> wrote:
>>>
>>>> Anybody with experience in connecting Cisco IOS to Quagga NHRPD?
>>> I did extensive testing of opennhrp vs. Cisco, but quagga/nhrp is
>>> mostly tested against itself and opennhrp only. I have not had
>>> opportunity to do testing against Cisco, so this is good info.
>>>
>>>> Another Linux box connects to DMVPN hub without any issues.
>>>> Config should be fine but there seems to be an incompatibility
>>>> between Quagga and IOS.
>>>> Any inputs/experiences with this issue?
>>>> Just saw one thing in source code ... quagga expects prefix 0xff
>>>> and IOS seems to report prefix 0x20 (32)
>>>> Happy to help dev and test patches if needed :)
>>> Your observation is correct. This makes the difference. RFC2332
>>> states that if prefix length must be set to 0xff if unique bit is
>>> set - and now reading the code I must've been writing only the
>>> unique mode handling. Since that is usually the desired
>>> functionality.
>>>
>>> Now looking at your Cisco config (there's no "ip nhrp registration
>>> non-unique"), the unique bit should be set, and prefix length
>>> should be 0xff. So Cisco might be breaking RFC here. Perhaps you
>>> could get a packet capture to display what's going on?
>>>
>>> opennhrp did handle 0xff and a host sized prefix length equally. So
>>> perhaps we should do same in quagga/nhrp.
>>>
>>> Quagga/NHRP could also be improved to handle non-unique things. This
>>> seems to be requirement since Cisco expects this mode if the spoke
>>> is having a dynamic IP that may change often. Cisco treats
>>> non-unique mode as "replace the previous IP".
> Subject: [PATCH] nhrp: improve CIE prefix length handling
>
> RFC2332 states that prefix length MUST be 0xff for unique bindings.
> However, it seems at least some Cisco firmwares use host prefix
> length instead (which on wire level makes sense). Relax the handling
> of prefix length to treat all value longer than address length as
> 0xff. Additionally treat 0x00 the same way too, this is required
> by the RFC. This also fixes the prefix length address family to be
> checked against protocol address.
> ---
>  nhrpd/nhrp_nhs.c      |  2 +-
>  nhrpd/nhrp_peer.c     | 11 ++++++++---
>  nhrpd/nhrp_shortcut.c |  2 +-
>  3 files changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c
> index 7a5d2393..535f9559 100644
> --- a/nhrpd/nhrp_nhs.c
> +++ b/nhrpd/nhrp_nhs.c
> @@ -181,7 +181,7 @@ static int nhrp_reg_send_req(struct thread *t)
>  	hdr->flags |= htons(NHRP_FLAG_REGISTRATION_NAT);
>  	ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS);
>  	cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &nifp->nbma, &if_ad->addr);
> -	cie->prefix_length = 8 * sockunion_get_addrlen(&nifp->nbma);
> +	cie->prefix_length = 8 * sockunion_get_addrlen(&if_ad->addr);
>  	nhrp_ext_complete(zb, ext);
>  
>  	nhrp_packet_complete(zb, hdr);
> diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
> index 728fa1c4..5095d55a 100644
> --- a/nhrpd/nhrp_peer.c
> +++ b/nhrpd/nhrp_peer.c
> @@ -383,11 +383,12 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
>  	struct nhrp_extension_header *ext;
>  	struct nhrp_cache *c;
>  	union sockunion cie_nbma, cie_proto, *proto_addr, *nbma_addr, *nbma_natoa;
> -	int holdtime, natted = 0;
> +	int holdtime, prefix_len, hostprefix_len, natted = 0;
>  	size_t paylen;
>  	void *pay;
>  
>  	debugf(NHRP_DEBUG_COMMON, "Parsing and replying to Registration Req");
> +	hostprefix_len = 8 * sockunion_get_addrlen(&p->if_ad->addr);
>  
>  	if (!sockunion_same(&p->src_nbma, &p->peer->vc->remote.nbma))
>  		natted = 1;
> @@ -409,13 +410,17 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
>  	zbuf_init(&payload, pay, paylen, paylen);
>  
>  	while ((cie = nhrp_cie_pull(&payload, hdr, &cie_nbma, &cie_proto)) != NULL) {
> -		if (cie->prefix_length != 0xff && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) {
> +		prefix_len = cie->prefix_length;
> +		if (prefix_len == 0 || prefix_len >= hostprefix_len)
> +			prefix_len = hostprefix_len;
> +
> +		if (prefix_len != hostprefix_len && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) {
>  			cie->code = NHRP_CODE_BINDING_NON_UNIQUE;
>  			continue;
>  		}
>  
>  		/* We currently support only unique prefix registrations */
> -		if (cie->prefix_length != 0xff) {
> +		if (prefix_len != hostprefix_len) {
>  			cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED;
>  			continue;
>  		}
> diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c
> index 421f2886..60c63929 100644
> --- a/nhrpd/nhrp_shortcut.c
> +++ b/nhrpd/nhrp_shortcut.c
> @@ -224,7 +224,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, void *ar
>  	prefix.prefixlen = cie->prefix_length;
>  
>  	/* Sanity check prefix length */
> -	if (prefix.prefixlen >= 8*prefix_blen(&prefix)) {
> +	if (prefix.prefixlen >= 8*prefix_blen(&prefix) || prefix.prefixlen == 0) {
>  		prefix.prefixlen = 8*prefix_blen(&prefix);
>  	} else if (nhrp_route_address(NULL, &pp->dst_proto, &route_prefix, NULL) == NHRP_ROUTE_NBMA_NEXTHOP) {
>  		if (prefix.prefixlen < route_prefix.prefixlen)





More information about the Quagga-dev mailing list