diff --git a/src/lldpd/patch/0002-use-a-different-socket-for-changes-and-queries.patch b/src/lldpd/patch/0002-use-a-different-socket-for-changes-and-queries.patch new file mode 100644 index 0000000000..139b26e528 --- /dev/null +++ b/src/lldpd/patch/0002-use-a-different-socket-for-changes-and-queries.patch @@ -0,0 +1,191 @@ +diff --git a/src/daemon/netlink.c b/src/daemon/netlink.c +index 55f9b66..e7db1fc 100644 +--- a/src/daemon/netlink.c ++++ b/src/daemon/netlink.c +@@ -38,7 +38,8 @@ struct netlink_req { + }; + + struct lldpd_netlink { +- int nl_socket; ++ int nl_socket_queries; ++ int nl_socket_changes; + int nl_socket_recv_size; + /* Cache */ + struct interfaces_device_list *devices; +@@ -94,34 +95,35 @@ netlink_socket_set_buffer_size(int s, int optname, const char *optname_str, int + * @return 0 on success, -1 otherwise + */ + static int +-netlink_connect(struct lldpd *cfg, int protocol, unsigned groups) ++netlink_connect(struct lldpd *cfg, unsigned groups) + { +- int s; ++ int s1 = -1, s2 = -1; + struct sockaddr_nl local = { .nl_family = AF_NETLINK, + .nl_pid = 0, + .nl_groups = groups }; + +- /* Open Netlink socket */ +- log_debug("netlink", "opening netlink socket"); +- s = socket(AF_NETLINK, SOCK_RAW, protocol); +- if (s == -1) { +- log_warn("netlink", "unable to open netlink socket"); +- return -1; ++ /* Open Netlink socket for subscriptions */ ++ log_debug("netlink", "opening netlink sockets"); ++ s1 = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); ++ if (s1 == -1) { ++ log_warn("netlink", "unable to open netlink socket for changes"); ++ goto error; + } + if (NETLINK_SEND_BUFSIZE && +- netlink_socket_set_buffer_size(s, SO_SNDBUF, "SO_SNDBUF", ++ netlink_socket_set_buffer_size(s1, SO_SNDBUF, "SO_SNDBUF", + NETLINK_SEND_BUFSIZE) == -1) { +- close(s); +- return -1; ++ log_warn("netlink", "unable to set send buffer size"); ++ goto error; + } + +- int rc = netlink_socket_set_buffer_size(s, SO_RCVBUF, "SO_RCVBUF", ++ int rc = netlink_socket_set_buffer_size(s1, SO_RCVBUF, "SO_RCVBUF", + NETLINK_RECEIVE_BUFSIZE); + switch (rc) { + case -1: +- close(s); +- return -1; ++ log_warn("netlink", "unable to set receiver buffer size"); ++ goto error; + case -2: ++ /* Cannot set size */ + cfg->g_netlink->nl_socket_recv_size = 0; + break; + default: +@@ -129,13 +131,24 @@ netlink_connect(struct lldpd *cfg, int protocol, unsigned groups) + break; + } + if (groups && +- bind(s, (struct sockaddr *)&local, sizeof(struct sockaddr_nl)) < 0) { ++ bind(s1, (struct sockaddr *)&local, sizeof(struct sockaddr_nl)) < 0) { + log_warn("netlink", "unable to bind netlink socket"); +- close(s); +- return -1; ++ goto error; + } +- cfg->g_netlink->nl_socket = s; ++ ++ /* Opening Netlink socket to for queries */ ++ s2 = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); ++ if (s2 == -1) { ++ log_warn("netlink", "unable to open netlink socket for queries"); ++ goto error; ++ } ++ cfg->g_netlink->nl_socket_changes = s1; ++ cfg->g_netlink->nl_socket_queries = s2; + return 0; ++error: ++ if (s1 != -1) close(s1); ++ if (s2 != -1) close(s2); ++ return -1; + } + + /** +@@ -525,13 +538,12 @@ netlink_merge(struct interfaces_device *old, struct interfaces_device *new) + * @return 0 on success, -1 on error + */ + static int +-netlink_recv(struct lldpd *cfg, struct interfaces_device_list *ifs, ++netlink_recv(struct lldpd *cfg, int s, struct interfaces_device_list *ifs, + struct interfaces_address_list *ifas) + { + int end = 0, ret = 0, flags, retry = 0; + struct iovec iov; + int link_update = 0; +- int s = cfg->g_netlink->nl_socket; + + struct interfaces_device *ifdold; + struct interfaces_device *ifdnew; +@@ -570,8 +582,10 @@ netlink_recv(struct lldpd *cfg, struct interfaces_device_list *ifs, + } + int rsize = cfg->g_netlink->nl_socket_recv_size; + if (errno == ENOBUFS && rsize > 0 && +- rsize < NETLINK_MAX_RECEIVE_BUFSIZE) { +- /* Try to increase buffer size */ ++ rsize < NETLINK_MAX_RECEIVE_BUFSIZE && ++ s == cfg->g_netlink->nl_socket_changes) { ++ /* Try to increase buffer size, only for the ++ * socket used to receive changes */ + rsize *= 2; + if (rsize > NETLINK_MAX_RECEIVE_BUFSIZE) { + rsize = NETLINK_MAX_RECEIVE_BUFSIZE; +@@ -843,7 +857,7 @@ netlink_subscribe_changes(struct lldpd *cfg) + netlink_group_mask(RTNLGRP_IPV4_IFADDR) | + netlink_group_mask(RTNLGRP_IPV6_IFADDR); + +- return netlink_connect(cfg, NETLINK_ROUTE, groups); ++ return netlink_connect(cfg, groups); + } + + /** +@@ -852,7 +866,8 @@ static void + netlink_change_cb(struct lldpd *cfg) + { + if (cfg->g_netlink == NULL) return; +- netlink_recv(cfg, cfg->g_netlink->devices, cfg->g_netlink->addresses); ++ netlink_recv(cfg, cfg->g_netlink->nl_socket_changes, cfg->g_netlink->devices, ++ cfg->g_netlink->addresses); + } + + /** +@@ -897,22 +912,24 @@ netlink_initialize(struct lldpd *cfg) + } + TAILQ_INIT(ifs); + +- if (netlink_send(cfg->g_netlink->nl_socket, RTM_GETADDR, AF_UNSPEC, 1) == -1) ++ if (netlink_send(cfg->g_netlink->nl_socket_queries, RTM_GETADDR, AF_UNSPEC, ++ 1) == -1) + goto end; +- netlink_recv(cfg, NULL, ifaddrs); +- if (netlink_send(cfg->g_netlink->nl_socket, RTM_GETLINK, AF_PACKET, 2) == -1) ++ netlink_recv(cfg, cfg->g_netlink->nl_socket_queries, NULL, ifaddrs); ++ if (netlink_send(cfg->g_netlink->nl_socket_queries, RTM_GETLINK, AF_PACKET, ++ 2) == -1) + goto end; +- netlink_recv(cfg, ifs, NULL); ++ netlink_recv(cfg, cfg->g_netlink->nl_socket_queries, ifs, NULL); + #ifdef ENABLE_DOT1 + /* If we have a bridge, search for VLAN-aware bridges */ + TAILQ_FOREACH (iff, ifs, next) { + if (iff->type & IFACE_BRIDGE_T) { + log_debug("netlink", + "interface %s is a bridge, check for VLANs", iff->name); +- if (netlink_send(cfg->g_netlink->nl_socket, RTM_GETLINK, ++ if (netlink_send(cfg->g_netlink->nl_socket_queries, RTM_GETLINK, + AF_BRIDGE, 3) == -1) + goto end; +- netlink_recv(cfg, ifs, NULL); ++ netlink_recv(cfg, cfg->g_netlink->nl_socket_queries, ifs, NULL); + break; + } + } +@@ -920,7 +937,7 @@ netlink_initialize(struct lldpd *cfg) + + /* Listen to any future change */ + cfg->g_iface_cb = netlink_change_cb; +- if (levent_iface_subscribe(cfg, cfg->g_netlink->nl_socket) == -1) { ++ if (levent_iface_subscribe(cfg, cfg->g_netlink->nl_socket_changes) == -1) { + goto end; + } + +@@ -937,7 +954,10 @@ void + netlink_cleanup(struct lldpd *cfg) + { + if (cfg->g_netlink == NULL) return; +- if (cfg->g_netlink->nl_socket != -1) close(cfg->g_netlink->nl_socket); ++ if (cfg->g_netlink->nl_socket_changes != -1) ++ close(cfg->g_netlink->nl_socket_changes); ++ if (cfg->g_netlink->nl_socket_queries != -1) ++ close(cfg->g_netlink->nl_socket_queries); + interfaces_free_devices(cfg->g_netlink->devices); + interfaces_free_addresses(cfg->g_netlink->addresses); diff --git a/src/lldpd/patch/series b/src/lldpd/patch/series index 8aa5ab8d8f..c92e03c1ba 100644 --- a/src/lldpd/patch/series +++ b/src/lldpd/patch/series @@ -1,2 +1,3 @@ -# This series applies on GIT commit 396961a038a38675d46f96eaa7b430b2a1f8701b +# This series applies on GIT commit 7a595f1adfa4ae5302ba7953e14fd69c8579aa16 0001-return-error-when-port-does-not-exist.patch +0002-use-a-different-socket-for-changes-and-queries.patch diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel index 8d5dee78ad..dbb27c6fd2 160000 --- a/src/sonic-linux-kernel +++ b/src/sonic-linux-kernel @@ -1 +1 @@ -Subproject commit 8d5dee78adddc75ff061b591aa748e86633c8379 +Subproject commit dbb27c6fd2f01b04b4d8a2f5023ddfdd9da389ec diff --git a/src/sonic-restapi b/src/sonic-restapi index 5c8f3d73ce..66d16050ae 160000 --- a/src/sonic-restapi +++ b/src/sonic-restapi @@ -1 +1 @@ -Subproject commit 5c8f3d73cee348e437f6bd81f1397f301ae48f64 +Subproject commit 66d16050ae8645a7bacf10b6b444f5b9be118f8d diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index a979a0c8c7..eef8da65bb 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -144,6 +144,7 @@ 'sonic-serial-console.yang', 'sonic-smart-switch.yang', 'sonic-srv6.yang', + 'sonic-ztp.yang', ] class my_build_py(build_py): diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 73274732e0..fdc0dfed6e 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -3031,6 +3031,17 @@ "DEBUG_COUNTER_DROP_REASON": { "DEBUG_4|DIP_LINK_LOCAL": {}, "DEBUG_4|SIP_LINK_LOCAL": {} + }, + "ZTP" : { + "mode" : { + "profile" : "active", + "inband" : "true", + "out-of-band" : "true", + "ipv4" : "true", + "ipv6" : "true", + "product-name" : "product name", + "serial-no" : "1234-5678-91A" + } } }, "SAMPLE_CONFIG_DB_UNKNOWN": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/ztp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/ztp.json new file mode 100644 index 0000000000..5911f1ca66 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/ztp.json @@ -0,0 +1,25 @@ +{ + "ZTP_VALID": { + "desc": "ZTP All Valid" + }, + "ZTP_PROFILE_INVALID": { + "desc": "ZTP profile invalid", + "eStrKey" : "InvalidValue" + }, + "ZTP_INBAND_INVALID": { + "desc": "ZTP inband invalid", + "eStrKey" : "InvalidValue" + }, + "ZTP_OUTOFBAND_INVALID": { + "desc": "ZTP out-of-band invalid", + "eStrKey" : "InvalidValue" + }, + "ZTP_IPV4_INVALID": { + "desc": "ZTP ipv4 invalid", + "eStrKey" : "InvalidValue" + }, + "ZTP_IPV6_INVALID": { + "desc": "ZTP ipv6 invalid", + "eStrKey" : "InvalidValue" + } +} diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/ztp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/ztp.json new file mode 100644 index 0000000000..471d1f22fd --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/ztp.json @@ -0,0 +1,66 @@ +{ + "ZTP_VALID": { + "sonic-ztp:sonic-ztp": { + "sonic-ztp:ZTP": { + "sonic-ztp:mode": { + "profile" : "active", + "inband" : "true", + "out-of-band" : "true", + "ipv4" : "true", + "ipv6" : "true", + "product-name" : "product name", + "serial-no" : "1234-5678-9A1" + } + } + } + }, + "ZTP_PROFILE_INVALID": { + "sonic-ztp:sonic-ztp": { + "sonic-ztp:ZTP": { + "sonic-ztp:mode": { + "profile" : "invalid" + } + } + } + }, + "ZTP_INBAND_INVALID": { + "sonic-ztp:sonic-ztp": { + "sonic-ztp:ZTP": { + "sonic-ztp:mode": { + "profile" : "active", + "inband": "invalid" + } + } + } + }, + "ZTP_OUTOFBAND_INVALID": { + "sonic-ztp:sonic-ztp": { + "sonic-ztp:ZTP": { + "sonic-ztp:mode": { + "profile" : "active", + "out-of-band": "invalid" + } + } + } + }, + "ZTP_IPV4_INVALID": { + "sonic-ztp:sonic-ztp": { + "sonic-ztp:ZTP": { + "sonic-ztp:mode": { + "profile" : "active", + "ipv4": "invalid" + } + } + } + }, + "ZTP_IPV6_INVALID": { + "sonic-ztp:sonic-ztp": { + "sonic-ztp:ZTP": { + "sonic-ztp:mode": { + "profile" : "active", + "ipv6": "invalid" + } + } + } + } +} diff --git a/src/sonic-yang-models/yang-models/sonic-ztp.yang b/src/sonic-yang-models/yang-models/sonic-ztp.yang new file mode 100644 index 0000000000..31743f6f33 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-ztp.yang @@ -0,0 +1,70 @@ +module sonic-ztp { + + yang-version 1.1; + + namespace "http://github.com/sonic-net/sonic-ztp"; + prefix ztp; + + description "ZTP YANG Module for SONiC OS"; + + revision 2025-04-03 { + description "First Revision"; + } + + container sonic-ztp { + + container ZTP { + + description "ZTP part of config_db.json used only temporarily during ZTP provisioning"; + + container mode { + + leaf profile { + type enumeration { + enum active; + } + description "Whether or not ZTP is active"; + } + + leaf inband { + type boolean; + default true; + description "If in-band ports are allowed to be used for ZTP"; + } + + leaf out-of-band { + type boolean; + default true; + description "If out-of-band ports are allowed to be used for ZTP"; + } + + leaf ipv4 { + type boolean; + default true; + description "If ipv4 is allowed to be used for ZTP"; + } + + leaf ipv6 { + type boolean; + default true; + description "If ipv6 is allowed to be used for ZTP"; + } + + leaf product-name { + type string; + description "Product string as returned from decode-syseeprom -p"; + } + + leaf serial-no { + type string; + description "Serial number as returned from decode-syseeprom -s"; + } + + } + /* end of container mode */ + } + /* end of container ZTP */ + } + /* end of top level container */ +} +/* end of module sonic-ztp */