Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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);
3 changes: 2 additions & 1 deletion src/lldpd/patch/series
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/sonic-restapi
1 change: 1 addition & 0 deletions src/sonic-yang-models/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
'sonic-serial-console.yang',
'sonic-smart-switch.yang',
'sonic-srv6.yang',
'sonic-ztp.yang',
]

class my_build_py(build_py):
Expand Down
11 changes: 11 additions & 0 deletions src/sonic-yang-models/tests/files/sample_config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
25 changes: 25 additions & 0 deletions src/sonic-yang-models/tests/yang_model_tests/tests/ztp.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -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"
}
}
}
}
}
70 changes: 70 additions & 0 deletions src/sonic-yang-models/yang-models/sonic-ztp.yang
Original file line number Diff line number Diff line change
@@ -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 */