@@ -347,6 +347,66 @@ static const struct route_map_rule_cmd route_match_peer_cmd = {
347
347
route_match_peer_free
348
348
};
349
349
350
+ static enum route_map_cmd_result_t route_match_src_peer (void * rule , const struct prefix * prefix ,
351
+ void * object )
352
+ {
353
+ struct bgp_match_peer_compiled * pc ;
354
+ union sockunion * su ;
355
+ struct peer_group * group ;
356
+ struct peer * peer ;
357
+ struct listnode * node , * nnode ;
358
+ struct bgp_path_info * bpi ;
359
+
360
+ pc = rule ;
361
+ su = & pc -> su ;
362
+ bpi = object ;
363
+ peer = bpi -> from ;
364
+
365
+ /* Fallback to destination (current) peer. This is mostly
366
+ * happens if `match src-peer ...` is used at incoming direction.
367
+ */
368
+ if (!peer )
369
+ peer = bpi -> peer ;
370
+
371
+ if (!peer )
372
+ return RMAP_NOMATCH ;
373
+
374
+ if (pc -> interface ) {
375
+ if (!peer -> conf_if && !peer -> group )
376
+ return RMAP_NOMATCH ;
377
+
378
+ if (peer -> conf_if && strcmp (peer -> conf_if , pc -> interface ) == 0 )
379
+ return RMAP_MATCH ;
380
+
381
+ if (peer -> group && strcmp (peer -> group -> name , pc -> interface ) == 0 )
382
+ return RMAP_MATCH ;
383
+
384
+ return RMAP_NOMATCH ;
385
+ }
386
+
387
+ if (!CHECK_FLAG (peer -> sflags , PEER_STATUS_GROUP )) {
388
+ if (sockunion_same (su , & peer -> connection -> su ))
389
+ return RMAP_MATCH ;
390
+
391
+ return RMAP_NOMATCH ;
392
+ }
393
+
394
+ group = peer -> group ;
395
+ for (ALL_LIST_ELEMENTS (group -> peer , node , nnode , peer )) {
396
+ if (sockunion_same (su , & peer -> connection -> su ))
397
+ return RMAP_MATCH ;
398
+ }
399
+
400
+ return RMAP_NOMATCH ;
401
+ }
402
+
403
+ static const struct route_map_rule_cmd route_match_src_peer_cmd = {
404
+ "src-peer" ,
405
+ route_match_src_peer ,
406
+ route_match_peer_compile ,
407
+ route_match_peer_free
408
+ };
409
+
350
410
#ifdef HAVE_SCRIPTING
351
411
352
412
enum frrlua_rm_status {
@@ -5287,6 +5347,52 @@ DEFUN_YANG (no_match_peer,
5287
5347
return nb_cli_apply_changes (vty , NULL );
5288
5348
}
5289
5349
5350
+ DEFPY_YANG (match_src_peer ,
5351
+ match_src_peer_cmd ,
5352
+ "match src-peer <A.B.C.D$addrv4|X:X::X:X$addrv6|WORD$intf>" ,
5353
+ MATCH_STR
5354
+ "Match source peer address\n"
5355
+ "IP address of peer\n"
5356
+ "IPv6 address of peer\n"
5357
+ "Interface name of peer or peer group name\n" )
5358
+ {
5359
+ const char * xpath = "./match-condition[condition='frr-bgp-route-map:src-peer']" ;
5360
+ char xpath_value [XPATH_MAXLEN ];
5361
+
5362
+ nb_cli_enqueue_change (vty , xpath , NB_OP_CREATE , NULL );
5363
+
5364
+ snprintf (xpath_value , sizeof (xpath_value ),
5365
+ "%s/rmap-match-condition/frr-bgp-route-map:src-peer-ipv4-address" , xpath );
5366
+ nb_cli_enqueue_change (vty , xpath_value , addrv4_str ? NB_OP_MODIFY : NB_OP_DESTROY ,
5367
+ addrv4_str );
5368
+ snprintf (xpath_value , sizeof (xpath_value ),
5369
+ "%s/rmap-match-condition/frr-bgp-route-map:src-peer-ipv6-address" , xpath );
5370
+ nb_cli_enqueue_change (vty , xpath_value , addrv6_str ? NB_OP_MODIFY : NB_OP_DESTROY ,
5371
+ addrv6_str );
5372
+ snprintf (xpath_value , sizeof (xpath_value ),
5373
+ "%s/rmap-match-condition/frr-bgp-route-map:src-peer-interface" , xpath );
5374
+ nb_cli_enqueue_change (vty , xpath_value , intf ? NB_OP_MODIFY : NB_OP_DESTROY , intf );
5375
+
5376
+ return nb_cli_apply_changes (vty , NULL );
5377
+ }
5378
+
5379
+ DEFUN_YANG (no_match_src_peer ,
5380
+ no_match_src_peer_cmd ,
5381
+ "no match src-peer [<A.B.C.D|X:X::X:X|WORD>]" ,
5382
+ NO_STR
5383
+ MATCH_STR
5384
+ "Match peer address\n"
5385
+ "IP address of peer\n"
5386
+ "IPv6 address of peer\n"
5387
+ "Interface name of peer\n" )
5388
+ {
5389
+ const char * xpath = "./match-condition[condition='frr-bgp-route-map:src-peer']" ;
5390
+
5391
+ nb_cli_enqueue_change (vty , xpath , NB_OP_DESTROY , NULL );
5392
+
5393
+ return nb_cli_apply_changes (vty , NULL );
5394
+ }
5395
+
5290
5396
#ifdef HAVE_SCRIPTING
5291
5397
DEFUN_YANG (match_script ,
5292
5398
match_script_cmd ,
@@ -7778,6 +7884,7 @@ void bgp_route_map_init(void)
7778
7884
route_map_no_set_tag_hook (generic_set_delete );
7779
7885
7780
7886
route_map_install_match (& route_match_peer_cmd );
7887
+ route_map_install_match (& route_match_src_peer_cmd );
7781
7888
route_map_install_match (& route_match_alias_cmd );
7782
7889
route_map_install_match (& route_match_local_pref_cmd );
7783
7890
#ifdef HAVE_SCRIPTING
@@ -7845,6 +7952,8 @@ void bgp_route_map_init(void)
7845
7952
7846
7953
install_element (RMAP_NODE , & match_peer_cmd );
7847
7954
install_element (RMAP_NODE , & match_peer_local_cmd );
7955
+ install_element (RMAP_NODE , & match_src_peer_cmd );
7956
+ install_element (RMAP_NODE , & no_match_src_peer_cmd );
7848
7957
install_element (RMAP_NODE , & no_match_peer_cmd );
7849
7958
install_element (RMAP_NODE , & match_ip_route_source_cmd );
7850
7959
install_element (RMAP_NODE , & no_match_ip_route_source_cmd );
0 commit comments