mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-10-31 18:40:52 +00:00 
			
		
		
		
	Merge pull request #13354 from zmw12306/parse_request_subtlv
babeld: add parse_request_subtlv into parse_packet
This commit is contained in:
		
						commit
						c12a40fee3
					
				| @ -48,6 +48,13 @@ static const unsigned char tlv_min_length[MESSAGE_MAX + 1] = | ||||
|     [ MESSAGE_MH_REQUEST ] = 14, | ||||
| }; | ||||
| 
 | ||||
| /* Checks whether an AE exists or must be silently ignored */ | ||||
| static bool | ||||
| known_ae(int ae) | ||||
| { | ||||
|     return ae <= 4; | ||||
| } | ||||
| 
 | ||||
| /* Parse a network prefix, encoded in the somewhat baroque compressed
 | ||||
|    representation used by Babel.  Return the number of bytes parsed. */ | ||||
| static int | ||||
| @ -276,6 +283,62 @@ parse_ihu_subtlv(const unsigned char *a, int alen, | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| parse_request_subtlv(int ae, const unsigned char *a, int alen, | ||||
|                      unsigned char *src_prefix, unsigned char *src_plen) | ||||
| { | ||||
|     int type, len, i = 0; | ||||
|     int have_src_prefix = 0; | ||||
| 
 | ||||
|     while(i < alen) { | ||||
|         type = a[0]; | ||||
|         if(type == SUBTLV_PAD1) { | ||||
|             i++; | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if(i + 2 > alen) | ||||
|             goto fail; | ||||
| 
 | ||||
|         len = a[i + 1]; | ||||
|         if(i + 2 + len > alen) | ||||
|             goto fail; | ||||
| 
 | ||||
|         if(type == SUBTLV_PADN) { | ||||
|             /* Nothing to do. */ | ||||
|         } else if(type == SUBTLV_SOURCE_PREFIX) { | ||||
|             int rc; | ||||
|             if(len < 1) | ||||
|                 goto fail; | ||||
|             if(a[i + 2] == 0) | ||||
|                 goto fail; | ||||
|             if(have_src_prefix != 0) | ||||
|                 goto fail; | ||||
|             rc = network_prefix(ae, a[i + 2], 0, a + i + 3, NULL, | ||||
|                                 len - 1, src_prefix); | ||||
|             if(rc < 0) | ||||
|                 goto fail; | ||||
|             if(ae==1) | ||||
|                 *src_plen = a[i + 2] + 96; | ||||
|             else | ||||
|                 *src_plen = a[i + 2]; | ||||
|             have_src_prefix = 1; | ||||
|         } else { | ||||
|             debugf(BABEL_DEBUG_COMMON,"Received unknown%s Route Request sub-TLV %d.", | ||||
|                    ((type & 0x80) != 0) ? " mandatory" : "", type); | ||||
|             if((type & 0x80) != 0) | ||||
|                 return -1; | ||||
|         } | ||||
| 
 | ||||
|         i += len + 2; | ||||
|     } | ||||
|     return 1; | ||||
| 
 | ||||
|  fail: | ||||
|     flog_err(EC_BABEL_PACKET, "Received truncated sub-TLV on Route Request."); | ||||
|     return -1; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| network_address(int ae, const unsigned char *a, unsigned int len, | ||||
|                 unsigned char *a_r) | ||||
| @ -612,8 +675,14 @@ parse_packet(const unsigned char *from, struct interface *ifp, | ||||
| 				 interval, neigh, nh, channels, | ||||
| 				 channels_len(channels)); | ||||
| 	} else if(type == MESSAGE_REQUEST) { | ||||
|             unsigned char prefix[16], plen; | ||||
|             int rc; | ||||
|             unsigned char prefix[16], src_prefix[16], plen, src_plen; | ||||
|             int rc, is_ss; | ||||
|             if(len < 2) goto fail; | ||||
|             if(!known_ae(message[2])) { | ||||
|                 debugf(BABEL_DEBUG_COMMON,"Received request with unknown AE %d. Ignoring.", | ||||
|                        message[2]); | ||||
|                 goto done; | ||||
|             } | ||||
|             rc = network_prefix(message[2], message[3], 0, | ||||
|                                 message + 4, NULL, len - 2, prefix); | ||||
|             if(rc < 0) goto fail; | ||||
| @ -621,8 +690,26 @@ parse_packet(const unsigned char *from, struct interface *ifp, | ||||
|             debugf(BABEL_DEBUG_COMMON,"Received request for %s from %s on %s.", | ||||
|                    message[2] == 0 ? "any" : format_prefix(prefix, plen), | ||||
|                    format_address(from), ifp->name); | ||||
|             if(message[2] == 1) { | ||||
|                 v4tov6(src_prefix, zeroes); | ||||
|                 src_plen = 96; | ||||
|             } else { | ||||
|                 memcpy(src_prefix, zeroes, 16); | ||||
|                 src_plen = 0; | ||||
|             } | ||||
|             rc = parse_request_subtlv(message[2], message + 4 + rc, | ||||
|                                       len - 2 - rc, src_prefix, &src_plen); | ||||
|             if(rc < 0) | ||||
|                 goto done; | ||||
|             is_ss = !is_default(src_prefix, src_plen); | ||||
|             if(message[2] == 0) { | ||||
|                 struct babel_interface *neigh_ifp =babel_get_if_nfo(neigh->ifp); | ||||
|                 if(is_ss) { | ||||
|                     /* Wildcard requests don't carry a source prefix. */ | ||||
|                     flog_err(EC_BABEL_PACKET, | ||||
| 			      "Received source-specific wildcard request."); | ||||
|                     goto done; | ||||
|                 } | ||||
|                 /* If a neighbour is requesting a full route dump from us,
 | ||||
|                    we might as well send it an IHU. */ | ||||
|                 send_ihu(neigh, NULL); | ||||
|  | ||||
| @ -34,6 +34,7 @@ Copyright (c) 2007, 2008 by Juliusz Chroboczek | ||||
| #define SUBTLV_PADN 1 | ||||
| #define SUBTLV_DIVERSITY 2 /* Also known as babelz. */ | ||||
| #define SUBTLV_TIMESTAMP 3 /* Used to compute RTT. */ | ||||
| #define SUBTLV_SOURCE_PREFIX 128 /* Source-specific routing. */ | ||||
| #define SUBTLV_MANDATORY 0x80 | ||||
| 
 | ||||
| extern unsigned short myseqno; | ||||
|  | ||||
| @ -104,6 +104,12 @@ void uchar_to_in6addr(struct in6_addr *dest, const unsigned char *src); | ||||
| int daemonise(void); | ||||
| extern const unsigned char v4prefix[16]; | ||||
| 
 | ||||
| static inline bool | ||||
| is_default(const unsigned char *prefix, int plen) | ||||
| { | ||||
|     return plen == 0 || (plen == 96 && v4mapped(prefix)); | ||||
| } | ||||
| 
 | ||||
| /* If debugging is disabled, we want to avoid calling format_address
 | ||||
|    for every omitted debugging message.  So debug is a macro.  But | ||||
|    vararg macros are not portable. */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Russ White
						Russ White