From 4f263d2208c2c378e618b2d0a7d88d15d66e1784 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 24 Apr 2025 15:55:45 +0200 Subject: [PATCH] lib: add support for next-csid instruction display in nexthops The next-csid term is only used by IETF; instead, the industry is using the uSID terminology defined in the linked document. Instead of displaying the next-csid instruction with the other flavors, replace the non microsid behavior with the associated microsid behavior. Example: - End becomes uN - End.X becomes uA - End.DT4 becomes uT4 - ... > # ip -6 route add 2008::1 encap seg6local action End flavors next-csid,psp dev dum1 > # show ipv6 route > [..] > K>* 2008::1/128 [0/1024] is directly connected, dum1, seg6local uN (PSP), weight 1, 00:00:05 > [..] > # show ipv6 route json > [..] > ,"2008::1/128":[{"prefix":"2008::1/128","prefixLen":128,"protocol":"kernel","vrfId":0, > "vrfName":"default","selected":true,"destSelected":true,"distance":0,"metric":1024,"installed":true, > "table":254,"internalStatus":16,"internalFlags":8,"internalNextHopNum":1,"internalNextHopActiveNum":1, > "nexthopGroupId":30,"installedNexthopGroupId":30,"uptime":"00:01:12","nexthops":[{"flags":3,"fib":true, > "directlyConnected":true,"interfaceIndex":19,"interfaceName":"dum1","active":true,"weight":1, > "seg6local":{"action":"uN","sidStructure":{"blockLen":0,"nodeLen":0,"funcLen":0,"argLen":0}}, > "seg6localContext":{"flavors":["psp"]}}]}] > [..] Link: https://datatracker.ietf.org/doc/html/draft-filsfils-spring-net-pgm-extension-srv6-usid Signed-off-by: Philippe Guibert --- lib/nexthop.c | 13 ++++++++----- lib/srv6.c | 31 ++++++++++++++++++------------- lib/srv6.h | 12 ++++++++++++ 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index c377b9cb00..cc8327f2aa 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -1316,9 +1316,10 @@ void nexthop_json_helper(json_object *json_nexthop, if (nexthop->nh_srv6) { json_seg6local = json_object_new_object(); json_object_string_add(json_seg6local, "action", - seg6local_action2str( - nexthop->nh_srv6 - ->seg6local_action)); + seg6local_action2str_with_next_csid( + nexthop->nh_srv6->seg6local_action, + seg6local_has_next_csid( + &nexthop->nh_srv6->seg6local_ctx))); json_seg6local_context = json_object_new_object(); json_object_object_add(json_nexthop, "seg6local", json_seg6local); @@ -1471,8 +1472,10 @@ void nexthop_vty_helper(struct vty *vty, const struct nexthop *nexthop, if (nexthop->nh_srv6->seg6local_action != ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) vty_out(vty, ", seg6local %s %s", - seg6local_action2str( - nexthop->nh_srv6->seg6local_action), + seg6local_action2str_with_next_csid(nexthop->nh_srv6->seg6local_action, + seg6local_has_next_csid( + &nexthop->nh_srv6 + ->seg6local_ctx)), buf); if (nexthop->nh_srv6->seg6_segs && IPV6_ADDR_CMP(&nexthop->nh_srv6->seg6_segs->seg[0], diff --git a/lib/srv6.c b/lib/srv6.c index 4e973e3642..40e4e58ac4 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -16,31 +16,31 @@ DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk"); DEFINE_MTYPE_STATIC(LIB, SRV6_SID_FORMAT, "SRv6 SID format"); DEFINE_MTYPE_STATIC(LIB, SRV6_SID_CTX, "SRv6 SID context"); -const char *seg6local_action2str(uint32_t action) +const char *seg6local_action2str_with_next_csid(uint32_t action, bool has_next_csid) { switch (action) { case ZEBRA_SEG6_LOCAL_ACTION_END: - return "End"; + return has_next_csid ? "uN" : "End"; case ZEBRA_SEG6_LOCAL_ACTION_END_X: - return "End.X"; + return has_next_csid ? "uA" : "End.X"; case ZEBRA_SEG6_LOCAL_ACTION_END_T: - return "End.T"; + return has_next_csid ? "uDT" : "End.T"; case ZEBRA_SEG6_LOCAL_ACTION_END_DX2: - return "End.DX2"; + return has_next_csid ? "uDX2" : "End.DX2"; case ZEBRA_SEG6_LOCAL_ACTION_END_DX6: - return "End.DX6"; + return has_next_csid ? "uDX6" : "End.DX6"; case ZEBRA_SEG6_LOCAL_ACTION_END_DX4: - return "End.DX4"; + return has_next_csid ? "uDX4" : "End.DX4"; case ZEBRA_SEG6_LOCAL_ACTION_END_DT6: - return "End.DT6"; + return has_next_csid ? "uDT6" : "End.DT6"; case ZEBRA_SEG6_LOCAL_ACTION_END_DT4: - return "End.DT4"; + return has_next_csid ? "uDT4" : "End.DT4"; case ZEBRA_SEG6_LOCAL_ACTION_END_B6: - return "End.B6"; + return has_next_csid ? "uB6" : "End.B6"; case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP: - return "End.B6.Encap"; + return has_next_csid ? "uB6.Encap" : "End.B6.Encap"; case ZEBRA_SEG6_LOCAL_ACTION_END_BM: - return "End.BM"; + return has_next_csid ? "uBM" : "End.BM"; case ZEBRA_SEG6_LOCAL_ACTION_END_S: return "End.S"; case ZEBRA_SEG6_LOCAL_ACTION_END_AS: @@ -48,7 +48,7 @@ const char *seg6local_action2str(uint32_t action) case ZEBRA_SEG6_LOCAL_ACTION_END_AM: return "End.AM"; case ZEBRA_SEG6_LOCAL_ACTION_END_DT46: - return "End.DT46"; + return has_next_csid ? "uDT46" : "End.DT46"; case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC: return "unspec"; default: @@ -56,6 +56,11 @@ const char *seg6local_action2str(uint32_t action) } } +const char *seg6local_action2str(uint32_t action) +{ + return seg6local_action2str_with_next_csid(action, false); +} + int snprintf_seg6_segs(char *str, size_t size, const struct seg6_segs *segs) { diff --git a/lib/srv6.h b/lib/srv6.h index 708792fb28..fd972e7216 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -203,6 +203,16 @@ enum srv6_endpoint_behavior_codepoint { SRV6_ENDPOINT_BEHAVIOR_OPAQUE = 0xFFFF, }; +/* + * Return true if next-csid behavior is used, false otherwise + */ +static inline bool seg6local_has_next_csid(const struct seg6local_context *ctx) +{ + const struct seg6local_flavors_info *flv_info = &ctx->flv; + + return CHECK_SRV6_FLV_OP(flv_info->flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID); +} + /* * Convert SRv6 endpoint behavior codepoints to human-friendly string. */ @@ -395,6 +405,8 @@ static inline void *sid_copy(struct in6_addr *dst, return memcpy(dst, src, sizeof(struct in6_addr)); } +const char *seg6local_action2str_with_next_csid(uint32_t action, bool has_next_csid); + const char * seg6local_action2str(uint32_t action); -- 2.39.5