* [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER
@ 2020-11-16 7:31 Martin Schiller
2020-11-16 7:31 ` [PATCH 2/6] net/x25: make neighbour params configurable Martin Schiller
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Martin Schiller @ 2020-11-16 7:31 UTC (permalink / raw)
To: andrew.hendry, davem, kuba, xie.he.0141
Cc: linux-x25, netdev, linux-kernel, Martin Schiller
and also by NETDEV_POST_TYPE_CHANGE/NETDEV_PRE_TYPE_CHANGE.
This change is needed so that the x25_neigh struct for an interface is
already created when it shows up and is kept independantly if the
interface goes UP or DOWN.
This is used in the next commit, where x25 params of an neighbour will
get configurable through ioctls.
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
include/net/x25.h | 2 ++
net/x25/af_x25.c | 19 +++++++++++++++++
net/x25/x25_link.c | 51 ++++++++++++++++++++++++++++++++++++++++------
3 files changed, 66 insertions(+), 6 deletions(-)
diff --git a/include/net/x25.h b/include/net/x25.h
index d7d6c2b4ffa7..af841c5ede28 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -231,6 +231,8 @@ int x25_backlog_rcv(struct sock *, struct sk_buff *);
/* x25_link.c */
void x25_link_control(struct sk_buff *, struct x25_neigh *, unsigned short);
+void x25_link_device_add(struct net_device *);
+void x25_link_device_remove(struct net_device *);
void x25_link_device_up(struct net_device *);
void x25_link_device_down(struct net_device *);
void x25_link_established(struct x25_neigh *);
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index a10487e7574c..d8e5ca251801 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -233,10 +233,20 @@ static int x25_device_event(struct notifier_block *this, unsigned long event,
#endif
) {
switch (event) {
+ case NETDEV_REGISTER:
+ pr_debug("X.25: got event NETDEV_REGISTER for device: %s\n", dev->name);
+ x25_link_device_add(dev);
+ break;
+ case NETDEV_POST_TYPE_CHANGE:
+ pr_debug("X.25: got event NETDEV_POST_TYPE_CHANGE for device: %s\n", dev->name);
+ x25_link_device_add(dev);
+ break;
case NETDEV_UP:
+ pr_debug("X.25: got event NETDEV_UP for device: %s\n", dev->name);
x25_link_device_up(dev);
break;
case NETDEV_GOING_DOWN:
+ pr_debug("X.25: got event NETDEV_GOING_DOWN for device: %s\n", dev->name);
nb = x25_get_neigh(dev);
if (nb) {
x25_terminate_link(nb);
@@ -244,10 +254,19 @@ static int x25_device_event(struct notifier_block *this, unsigned long event,
}
break;
case NETDEV_DOWN:
+ pr_debug("X.25: got event NETDEV_DOWN for device: %s\n", dev->name);
x25_kill_by_device(dev);
x25_route_device_down(dev);
x25_link_device_down(dev);
break;
+ case NETDEV_PRE_TYPE_CHANGE:
+ pr_debug("X.25: got event NETDEV_PRE_TYPE_CHANGE for device: %s\n", dev->name);
+ x25_link_device_remove(dev);
+ break;
+ case NETDEV_UNREGISTER:
+ pr_debug("X.25: got event NETDEV_UNREGISTER for device: %s\n", dev->name);
+ x25_link_device_remove(dev);
+ break;
}
}
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index fdae054b7dc1..22055ee40056 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -239,9 +239,19 @@ void x25_link_terminated(struct x25_neigh *nb)
/*
* Add a new device.
*/
-void x25_link_device_up(struct net_device *dev)
+void x25_link_device_add(struct net_device *dev)
{
- struct x25_neigh *nb = kmalloc(sizeof(*nb), GFP_ATOMIC);
+ struct x25_neigh *nb = x25_get_neigh(dev);
+
+ /*
+ * Check, if we already have a neighbour for this device
+ */
+ if (nb) {
+ x25_neigh_put(nb);
+ return;
+ }
+
+ nb = kmalloc(sizeof(*nb), GFP_ATOMIC);
if (!nb)
return;
@@ -268,6 +278,22 @@ void x25_link_device_up(struct net_device *dev)
write_unlock_bh(&x25_neigh_list_lock);
}
+/*
+ * A device is coming up
+ */
+void x25_link_device_up(struct net_device *dev)
+{
+ struct x25_neigh *nb = x25_get_neigh(dev);
+
+ if (!nb)
+ return;
+
+ nb->state = X25_LINK_STATE_1;
+ x25_establish_link(nb);
+
+ x25_neigh_put(nb);
+}
+
/**
* __x25_remove_neigh - remove neighbour from x25_neigh_list
* @nb: - neigh to remove
@@ -277,9 +303,6 @@ void x25_link_device_up(struct net_device *dev)
*/
static void __x25_remove_neigh(struct x25_neigh *nb)
{
- skb_queue_purge(&nb->queue);
- x25_stop_t20timer(nb);
-
if (nb->node.next) {
list_del(&nb->node);
x25_neigh_put(nb);
@@ -289,7 +312,7 @@ static void __x25_remove_neigh(struct x25_neigh *nb)
/*
* A device has been removed, remove its links.
*/
-void x25_link_device_down(struct net_device *dev)
+void x25_link_device_remove(struct net_device *dev)
{
struct x25_neigh *nb;
struct list_head *entry, *tmp;
@@ -308,6 +331,22 @@ void x25_link_device_down(struct net_device *dev)
write_unlock_bh(&x25_neigh_list_lock);
}
+/*
+ * A device is going down
+ */
+void x25_link_device_down(struct net_device *dev)
+{
+ struct x25_neigh *nb = x25_get_neigh(dev);
+
+ if (!nb)
+ return;
+
+ skb_queue_purge(&nb->queue);
+ x25_stop_t20timer(nb);
+
+ x25_neigh_put(nb);
+}
+
/*
* Given a device, return the neighbour address.
*/
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/6] net/x25: make neighbour params configurable
2020-11-16 7:31 [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Martin Schiller
@ 2020-11-16 7:31 ` Martin Schiller
2020-11-16 13:10 ` kernel test robot
2020-11-16 7:31 ` [PATCH 3/6] net/x25: replace x25_kill_by_device with x25_kill_by_neigh Martin Schiller
` (4 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Martin Schiller @ 2020-11-16 7:31 UTC (permalink / raw)
To: andrew.hendry, davem, kuba, xie.he.0141
Cc: linux-x25, netdev, linux-kernel, Martin Schiller
Extended struct x25_neigh and x25_subscrip_struct to configure following
params through SIOCX25SSUBSCRIP:
o mode (DTE/DCE)
o number of channels
o facilities (packet size, window size)
o timer T20
Based on this configuration options the follwing changes/extensions
where made:
o DTE/DCE handling to select the next lc (DCE=from bottom / DTE=from
top)
o DTE/DCE handling to set correct clear/reset/restart cause
o take default facilities from neighbour settings
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
include/net/x25.h | 7 ++-
include/uapi/linux/x25.h | 54 ++++++++--------
net/x25/af_x25.c | 132 ++++++++++++++++++++++++++++++++-------
net/x25/x25_facilities.c | 6 +-
net/x25/x25_link.c | 104 +++++++++++++++++++++++++-----
net/x25/x25_subr.c | 22 ++++++-
6 files changed, 255 insertions(+), 70 deletions(-)
diff --git a/include/net/x25.h b/include/net/x25.h
index af841c5ede28..6e8600456d39 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -140,6 +140,9 @@ struct x25_neigh {
struct net_device *dev;
unsigned int state;
unsigned int extended;
+ unsigned int dce;
+ unsigned int lc;
+ struct x25_facilities facilities;
struct sk_buff_head queue;
unsigned long t20;
struct timer_list t20timer;
@@ -164,6 +167,7 @@ struct x25_sock {
struct timer_list timer;
struct x25_causediag causediag;
struct x25_facilities facilities;
+ unsigned int socket_defined_facilities; /* set, if facilities changed by SIOCX25SFACILITIES */
struct x25_dte_facilities dte_facilities;
struct x25_calluserdata calluserdata;
unsigned long vc_facil_mask; /* inc_call facilities mask */
@@ -215,7 +219,8 @@ int x25_create_facilities(unsigned char *, struct x25_facilities *,
struct x25_dte_facilities *, unsigned long);
int x25_negotiate_facilities(struct sk_buff *, struct sock *,
struct x25_facilities *,
- struct x25_dte_facilities *);
+ struct x25_dte_facilities *,
+ struct x25_neigh *);
void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *);
/* x25_forward.c */
diff --git a/include/uapi/linux/x25.h b/include/uapi/linux/x25.h
index 034b7dc5593a..963848e94880 100644
--- a/include/uapi/linux/x25.h
+++ b/include/uapi/linux/x25.h
@@ -63,31 +63,6 @@ struct sockaddr_x25 {
struct x25_address sx25_addr; /* X.121 Address */
};
-/*
- * DTE/DCE subscription options.
- *
- * As this is missing lots of options, user should expect major
- * changes of this structure in 2.5.x which might break compatibilty.
- * The somewhat ugly dimension 200-sizeof() is needed to maintain
- * backward compatibility.
- */
-struct x25_subscrip_struct {
- char device[200-sizeof(unsigned long)];
- unsigned long global_facil_mask; /* 0 to disable negotiation */
- unsigned int extended;
-};
-
-/* values for above global_facil_mask */
-
-#define X25_MASK_REVERSE 0x01
-#define X25_MASK_THROUGHPUT 0x02
-#define X25_MASK_PACKET_SIZE 0x04
-#define X25_MASK_WINDOW_SIZE 0x08
-
-#define X25_MASK_CALLING_AE 0x10
-#define X25_MASK_CALLED_AE 0x20
-
-
/*
* Routing table control structure.
*/
@@ -127,6 +102,35 @@ struct x25_dte_facilities {
__u8 called_ae[20];
};
+/*
+ * DTE/DCE subscription options.
+ *
+ * As this is missing lots of options, user should expect major
+ * changes of this structure in 2.5.x which might break compatibilty.
+ * The somewhat ugly dimension 200-sizeof() is needed to maintain
+ * backward compatibility.
+ */
+struct x25_subscrip_struct {
+ char device[200-((2 * sizeof(unsigned long)) + sizeof(struct x25_facilities) + (2 * sizeof(unsigned int)))];
+ unsigned int dce;
+ unsigned int lc;
+ struct x25_facilities facilities;
+ unsigned long t20;
+ unsigned long global_facil_mask; /* 0 to disable negotiation */
+ unsigned int extended;
+};
+
+/* values for above global_facil_mask */
+
+#define X25_MASK_REVERSE 0x01
+#define X25_MASK_THROUGHPUT 0x02
+#define X25_MASK_PACKET_SIZE 0x04
+#define X25_MASK_WINDOW_SIZE 0x08
+
+#define X25_MASK_CALLING_AE 0x10
+#define X25_MASK_CALLED_AE 0x20
+
+
/*
* Call User Data structure.
*/
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index d8e5ca251801..439ae65ab7a8 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -72,8 +72,19 @@ static const struct proto_ops x25_proto_ops;
static const struct x25_address null_x25_address = {" "};
#ifdef CONFIG_COMPAT
+struct compat_x25_facilities {
+ compat_uint_t winsize_in, winsize_out;
+ compat_uint_t pacsize_in, pacsize_out;
+ compat_uint_t throughput;
+ compat_uint_t reverse;
+};
+
struct compat_x25_subscrip_struct {
- char device[200-sizeof(compat_ulong_t)];
+ char device[200-((2 * sizeof(compat_ulong_t)) + sizeof(struct compat_x25_facilities) + (2 * sizeof(compat_uint_t)))];
+ compat_uint_t dce;
+ compat_uint_t lc;
+ struct compat_x25_facilities facilities;
+ compat_ulong_t t20;
compat_ulong_t global_facil_mask;
compat_uint_t extended;
};
@@ -366,13 +377,26 @@ static unsigned int x25_new_lci(struct x25_neigh *nb)
unsigned int lci = 1;
struct sock *sk;
- while ((sk = x25_find_socket(lci, nb)) != NULL) {
- sock_put(sk);
- if (++lci == 4096) {
- lci = 0;
- break;
+ if (nb->dce) {
+ while ((sk = x25_find_socket(lci, nb)) != NULL) {
+ sock_put(sk);
+ if (++lci > nb->lc) {
+ lci = 0;
+ break;
+ }
+ cond_resched();
+ }
+ } else {
+ lci = nb->lc;
+
+ while ((sk = x25_find_socket(lci, nb)) != NULL) {
+ sock_put(sk);
+ if (--lci == 0) {
+ lci = 0;
+ break;
+ }
+ cond_resched();
}
- cond_resched();
}
return lci;
@@ -806,6 +830,10 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
if (!x25->neighbour)
goto out_put_route;
+ if (!x25->socket_defined_facilities)
+ memcpy(&x25->facilities, &x25->neighbour->facilities,
+ sizeof(struct x25_facilities));
+
x25_limit_facilities(&x25->facilities, x25->neighbour);
x25->lci = x25_new_lci(x25->neighbour);
@@ -1039,7 +1067,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
/*
* Try to reach a compromise on the requested facilities.
*/
- len = x25_negotiate_facilities(skb, sk, &facilities, &dte_facilities);
+ len = x25_negotiate_facilities(skb, sk, &facilities, &dte_facilities, nb);
if (len == -1)
goto out_sock_put;
@@ -1454,10 +1482,15 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
rc = x25_subscr_ioctl(cmd, argp);
break;
case SIOCX25GFACILITIES: {
+ rc = -EINVAL;
lock_sock(sk);
+ if (sk->sk_state != TCP_ESTABLISHED &&
+ !x25->socket_defined_facilities)
+ goto out_gfac_release;
rc = copy_to_user(argp, &x25->facilities,
sizeof(x25->facilities))
? -EFAULT : 0;
+out_gfac_release:
release_sock(sk);
break;
}
@@ -1471,16 +1504,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
lock_sock(sk);
if (sk->sk_state != TCP_LISTEN &&
sk->sk_state != TCP_CLOSE)
- goto out_fac_release;
+ goto out_sfac_release;
if (facilities.pacsize_in < X25_PS16 ||
facilities.pacsize_in > X25_PS4096)
- goto out_fac_release;
+ goto out_sfac_release;
if (facilities.pacsize_out < X25_PS16 ||
facilities.pacsize_out > X25_PS4096)
- goto out_fac_release;
+ goto out_sfac_release;
if (facilities.winsize_in < 1 ||
facilities.winsize_in > 127)
- goto out_fac_release;
+ goto out_sfac_release;
if (facilities.throughput) {
int out = facilities.throughput & 0xf0;
int in = facilities.throughput & 0x0f;
@@ -1488,19 +1521,20 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
facilities.throughput |=
X25_DEFAULT_THROUGHPUT << 4;
else if (out < 0x30 || out > 0xD0)
- goto out_fac_release;
+ goto out_sfac_release;
if (!in)
facilities.throughput |=
X25_DEFAULT_THROUGHPUT;
else if (in < 0x03 || in > 0x0D)
- goto out_fac_release;
+ goto out_sfac_release;
}
if (facilities.reverse &&
(facilities.reverse & 0x81) != 0x81)
- goto out_fac_release;
+ goto out_sfac_release;
x25->facilities = facilities;
+ x25->socket_defined_facilities = 1;
rc = 0;
-out_fac_release:
+out_sfac_release:
release_sock(sk);
break;
}
@@ -1652,6 +1686,9 @@ static int compat_x25_subscr_ioctl(unsigned int cmd,
struct net_device *dev;
int rc = -EINVAL;
+ if (cmd != SIOCX25GSUBSCRIP && cmd != SIOCX25SSUBSCRIP)
+ goto out;
+
rc = -EFAULT;
if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
goto out;
@@ -1665,28 +1702,75 @@ static int compat_x25_subscr_ioctl(unsigned int cmd,
if (nb == NULL)
goto out_dev_put;
- dev_put(dev);
-
if (cmd == SIOCX25GSUBSCRIP) {
read_lock_bh(&x25_neigh_list_lock);
x25_subscr.extended = nb->extended;
+ x25_subscr.dce = nb->dce;
+ x25_subscr.lc = nb->lc;
+ x25_subscr.facilities = nb->facilities;
+ x25_subscr.t20 = nb->t20;
x25_subscr.global_facil_mask = nb->global_facil_mask;
read_unlock_bh(&x25_neigh_list_lock);
rc = copy_to_user(x25_subscr32, &x25_subscr,
sizeof(*x25_subscr32)) ? -EFAULT : 0;
} else {
rc = -EINVAL;
- if (x25_subscr.extended == 0 || x25_subscr.extended == 1) {
- rc = 0;
- write_lock_bh(&x25_neigh_list_lock);
- nb->extended = x25_subscr.extended;
- nb->global_facil_mask = x25_subscr.global_facil_mask;
- write_unlock_bh(&x25_neigh_list_lock);
+
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+ if (x25_subscr.extended != 0 && x25_subscr.extended != 1)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.dce != 0 && x25_subscr.dce != 1)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.lc < 1 || x25_subscr.lc > 4095)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.pacsize_in < X25_PS16 ||
+ x25_subscr.facilities.pacsize_in > X25_PS4096)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.pacsize_out < X25_PS16 ||
+ x25_subscr.facilities.pacsize_out > X25_PS4096)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.winsize_in < 1 ||
+ x25_subscr.facilities.winsize_in > 127)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.throughput) {
+ int out = x25_subscr.facilities.throughput & 0xf0;
+ int in = x25_subscr.facilities.throughput & 0x0f;
+ if (!out)
+ x25_subscr.facilities.throughput |=
+ X25_DEFAULT_THROUGHPUT << 4;
+ else if (out < 0x30 || out > 0xD0)
+ goto out_dev_and_neigh_put;
+ if (!in)
+ x25_subscr.facilities.throughput |=
+ X25_DEFAULT_THROUGHPUT;
+ else if (in < 0x03 || in > 0x0D)
+ goto out_dev_and_neigh_put;
}
+ if (x25_subscr.facilities.reverse &&
+ (x25_subscr.facilities.reverse & 0x81) != 0x81)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.t20 < 1 * HZ || x25_subscr.t20 > 300 * HZ)
+ goto out_dev_and_neigh_put;
+
+ rc = 0;
+ write_lock_bh(&x25_neigh_list_lock);
+ nb->extended = x25_subscr.extended;
+ nb->dce = x25_subscr.dce;
+ nb->lc = x25_subscr.lc;
+ nb->facilities = x25_subscr.facilities;
+ nb->t20 = x25_subscr.t20;
+ nb->global_facil_mask = x25_subscr.global_facil_mask;
+ write_unlock_bh(&x25_neigh_list_lock);
}
+ dev_put(dev);
+
x25_neigh_put(nb);
out:
return rc;
+out_dev_and_neigh_put:
+ x25_neigh_put(nb);
out_dev_put:
dev_put(dev);
goto out;
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index 8e1a49b0c0dc..e6c9f9376206 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -263,13 +263,17 @@ int x25_create_facilities(unsigned char *buffer,
* The only real problem is with reverse charging.
*/
int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
- struct x25_facilities *new, struct x25_dte_facilities *dte)
+ struct x25_facilities *new, struct x25_dte_facilities *dte,
+ struct x25_neigh *nb)
{
struct x25_sock *x25 = x25_sk(sk);
struct x25_facilities *ours = &x25->facilities;
struct x25_facilities theirs;
int len;
+ if (!x25->socket_defined_facilities)
+ ours = &nb->facilities;
+
memset(&theirs, 0, sizeof(theirs));
memcpy(new, ours, sizeof(*new));
memset(dte, 0, sizeof(*dte));
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index 22055ee40056..fabac6331a59 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -125,8 +125,16 @@ static void x25_transmit_restart_request(struct x25_neigh *nb)
*dptr++ = nb->extended ? X25_GFI_EXTSEQ : X25_GFI_STDSEQ;
*dptr++ = 0x00;
*dptr++ = X25_RESTART_REQUEST;
- *dptr++ = 0x00;
- *dptr++ = 0;
+
+ *dptr = 0x00; /* cause */
+
+ /* set bit 8, if DTE and cause != 0x00 */
+ if (!nb->dce && *dptr != 0x00)
+ *dptr |= (unsigned char) 0x80;
+
+ dptr++;
+
+ *dptr++ = 0x00; /* diagnostic */
skb->sk = NULL;
@@ -181,8 +189,16 @@ void x25_transmit_clear_request(struct x25_neigh *nb, unsigned int lci,
X25_GFI_STDSEQ);
*dptr++ = (lci >> 0) & 0xFF;
*dptr++ = X25_CLEAR_REQUEST;
- *dptr++ = cause;
- *dptr++ = 0x00;
+
+ *dptr = cause; /* cause */
+
+ /* set bit 8, if DTE and cause != 0x00 */
+ if (!nb->dce && *dptr != 0x00)
+ *dptr |= (unsigned char) 0x80;
+
+ dptr++;
+
+ *dptr++ = 0x00; /* diagnostic */
skb->sk = NULL;
@@ -260,9 +276,19 @@ void x25_link_device_add(struct net_device *dev)
timer_setup(&nb->t20timer, x25_t20timer_expiry, 0);
dev_hold(dev);
- nb->dev = dev;
- nb->state = X25_LINK_STATE_0;
- nb->extended = 0;
+ nb->dev = dev;
+ nb->state = X25_LINK_STATE_0;
+ nb->extended = 0;
+ nb->dce = 0;
+ nb->lc = 10;
+ nb->facilities.winsize_in = X25_DEFAULT_WINDOW_SIZE;
+ nb->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
+ nb->facilities.pacsize_in = X25_DEFAULT_PACKET_SIZE;
+ nb->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
+ nb->facilities.throughput = 0; /* by default don't negotiate
+ throughput */
+ nb->facilities.reverse = X25_DEFAULT_REVERSE;
+ nb->t20 = sysctl_x25_restart_request_timeout;
/*
* Enables negotiation
*/
@@ -270,7 +296,6 @@ void x25_link_device_add(struct net_device *dev)
X25_MASK_THROUGHPUT |
X25_MASK_PACKET_SIZE |
X25_MASK_WINDOW_SIZE;
- nb->t20 = sysctl_x25_restart_request_timeout;
refcount_set(&nb->refcnt, 1);
write_lock_bh(&x25_neigh_list_lock);
@@ -395,28 +420,75 @@ int x25_subscr_ioctl(unsigned int cmd, void __user *arg)
if ((nb = x25_get_neigh(dev)) == NULL)
goto out_dev_put;
- dev_put(dev);
-
if (cmd == SIOCX25GSUBSCRIP) {
read_lock_bh(&x25_neigh_list_lock);
x25_subscr.extended = nb->extended;
+ x25_subscr.dce = nb->dce;
+ x25_subscr.lc = nb->lc;
+ x25_subscr.facilities = nb->facilities;
+ x25_subscr.t20 = nb->t20;
x25_subscr.global_facil_mask = nb->global_facil_mask;
read_unlock_bh(&x25_neigh_list_lock);
rc = copy_to_user(arg, &x25_subscr,
sizeof(x25_subscr)) ? -EFAULT : 0;
} else {
rc = -EINVAL;
- if (!(x25_subscr.extended && x25_subscr.extended != 1)) {
- rc = 0;
- write_lock_bh(&x25_neigh_list_lock);
- nb->extended = x25_subscr.extended;
- nb->global_facil_mask = x25_subscr.global_facil_mask;
- write_unlock_bh(&x25_neigh_list_lock);
+
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+ if (x25_subscr.extended != 0 && x25_subscr.extended != 1)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.dce != 0 && x25_subscr.dce != 1)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.lc < 1 || x25_subscr.lc > 4095)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.pacsize_in < X25_PS16 ||
+ x25_subscr.facilities.pacsize_in > X25_PS4096)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.pacsize_out < X25_PS16 ||
+ x25_subscr.facilities.pacsize_out > X25_PS4096)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.winsize_in < 1 ||
+ x25_subscr.facilities.winsize_in > 127)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.facilities.throughput) {
+ int out = x25_subscr.facilities.throughput & 0xf0;
+ int in = x25_subscr.facilities.throughput & 0x0f;
+ if (!out)
+ x25_subscr.facilities.throughput |=
+ X25_DEFAULT_THROUGHPUT << 4;
+ else if (out < 0x30 || out > 0xD0)
+ goto out_dev_and_neigh_put;
+ if (!in)
+ x25_subscr.facilities.throughput |=
+ X25_DEFAULT_THROUGHPUT;
+ else if (in < 0x03 || in > 0x0D)
+ goto out_dev_and_neigh_put;
}
+ if (x25_subscr.facilities.reverse &&
+ (x25_subscr.facilities.reverse & 0x81) != 0x81)
+ goto out_dev_and_neigh_put;
+ if (x25_subscr.t20 < 1 * HZ || x25_subscr.t20 > 300 * HZ)
+ goto out_dev_and_neigh_put;
+
+ rc = 0;
+ write_lock_bh(&x25_neigh_list_lock);
+ nb->extended = x25_subscr.extended;
+ nb->dce = x25_subscr.dce;
+ nb->lc = x25_subscr.lc;
+ nb->facilities = x25_subscr.facilities;
+ nb->t20 = x25_subscr.t20;
+ nb->global_facil_mask = x25_subscr.global_facil_mask;
+ write_unlock_bh(&x25_neigh_list_lock);
}
+ dev_put(dev);
+
x25_neigh_put(nb);
out:
return rc;
+out_dev_and_neigh_put:
+ x25_neigh_put(nb);
out_dev_put:
dev_put(dev);
goto out;
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index 0285aaa1e93c..b1bbabfbe26f 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -218,15 +218,31 @@ void x25_write_internal(struct sock *sk, int frametype)
case X25_CLEAR_REQUEST:
dptr = skb_put(skb, 3);
*dptr++ = frametype;
- *dptr++ = x25->causediag.cause;
+
+ *dptr = x25->causediag.cause;
+
+ /* set bit 8, if DTE and cause != 0x00 */
+ if (!x25->neighbour->dce && *dptr != 0x00)
+ *dptr |= (unsigned char) 0x80;
+
+ dptr++;
+
*dptr++ = x25->causediag.diagnostic;
break;
case X25_RESET_REQUEST:
dptr = skb_put(skb, 3);
*dptr++ = frametype;
- *dptr++ = 0x00; /* XXX */
- *dptr++ = 0x00; /* XXX */
+
+ *dptr = 0x00; /* cause */
+
+ /* set bit 8, if DTE and cause != 0x00 */
+ if (!x25->neighbour->dce && *dptr != 0x00)
+ *dptr |= (unsigned char) 0x80;
+
+ dptr++;
+
+ *dptr++ = 0x00; /* diagnostic */
break;
case X25_RR:
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/6] net/x25: replace x25_kill_by_device with x25_kill_by_neigh
2020-11-16 7:31 [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Martin Schiller
2020-11-16 7:31 ` [PATCH 2/6] net/x25: make neighbour params configurable Martin Schiller
@ 2020-11-16 7:31 ` Martin Schiller
2020-11-16 7:31 ` [PATCH 4/6] net/x25: support NETDEV_CHANGE notifier Martin Schiller
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Martin Schiller @ 2020-11-16 7:31 UTC (permalink / raw)
To: andrew.hendry, davem, kuba, xie.he.0141
Cc: linux-x25, netdev, linux-kernel, Martin Schiller
Remove unnecessary function x25_kill_by_device.
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
net/x25/af_x25.c | 22 +++++-----------------
1 file changed, 5 insertions(+), 17 deletions(-)
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 439ae65ab7a8..d98d1145500e 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -210,22 +210,6 @@ static void x25_remove_socket(struct sock *sk)
write_unlock_bh(&x25_list_lock);
}
-/*
- * Kill all bound sockets on a dropped device.
- */
-static void x25_kill_by_device(struct net_device *dev)
-{
- struct sock *s;
-
- write_lock_bh(&x25_list_lock);
-
- sk_for_each(s, &x25_list)
- if (x25_sk(s)->neighbour && x25_sk(s)->neighbour->dev == dev)
- x25_disconnect(s, ENETUNREACH, 0, 0);
-
- write_unlock_bh(&x25_list_lock);
-}
-
/*
* Handle device status changes.
*/
@@ -266,7 +250,11 @@ static int x25_device_event(struct notifier_block *this, unsigned long event,
break;
case NETDEV_DOWN:
pr_debug("X.25: got event NETDEV_DOWN for device: %s\n", dev->name);
- x25_kill_by_device(dev);
+ nb = x25_get_neigh(dev);
+ if (nb) {
+ x25_kill_by_neigh(nb);
+ x25_neigh_put(nb);
+ }
x25_route_device_down(dev);
x25_link_device_down(dev);
break;
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/6] net/x25: support NETDEV_CHANGE notifier
2020-11-16 7:31 [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Martin Schiller
2020-11-16 7:31 ` [PATCH 2/6] net/x25: make neighbour params configurable Martin Schiller
2020-11-16 7:31 ` [PATCH 3/6] net/x25: replace x25_kill_by_device with x25_kill_by_neigh Martin Schiller
@ 2020-11-16 7:31 ` Martin Schiller
2020-11-16 7:31 ` [PATCH 5/6] net/lapb: support netdev events Martin Schiller
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Martin Schiller @ 2020-11-16 7:31 UTC (permalink / raw)
To: andrew.hendry, davem, kuba, xie.he.0141
Cc: linux-x25, netdev, linux-kernel, Martin Schiller
This makes it possible to handle carrier lost and detection.
In case of carrier lost, we shutdown layer 3 and flush all sessions.
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
net/x25/af_x25.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index d98d1145500e..d61a154b94e4 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -266,6 +266,17 @@ static int x25_device_event(struct notifier_block *this, unsigned long event,
pr_debug("X.25: got event NETDEV_UNREGISTER for device: %s\n", dev->name);
x25_link_device_remove(dev);
break;
+ case NETDEV_CHANGE:
+ pr_debug("X.25: got event NETDEV_CHANGE for device: %s\n", dev->name);
+ if (!netif_carrier_ok(dev)) {
+ pr_debug("X.25: Carrier lost -> set link state down: %s\n", dev->name);
+ nb = x25_get_neigh(dev);
+ if (nb) {
+ x25_link_terminated(nb);
+ x25_neigh_put(nb);
+ }
+ }
+ break;
}
}
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/6] net/lapb: support netdev events
2020-11-16 7:31 [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Martin Schiller
` (2 preceding siblings ...)
2020-11-16 7:31 ` [PATCH 4/6] net/x25: support NETDEV_CHANGE notifier Martin Schiller
@ 2020-11-16 7:31 ` Martin Schiller
2020-11-16 7:31 ` [PATCH 6/6] net/lapb: fix t1 timer handling Martin Schiller
2020-11-16 8:45 ` [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Xie He
5 siblings, 0 replies; 9+ messages in thread
From: Martin Schiller @ 2020-11-16 7:31 UTC (permalink / raw)
To: andrew.hendry, davem, kuba, xie.he.0141
Cc: linux-x25, netdev, linux-kernel, Martin Schiller
This makes it possible to handle carrier loss and detection.
In case of Carrier Loss, layer 2 is terminated
In case of Carrier Detection, we start timer t1 on a DCE interface,
and on a DTE interface we change to state LAPB_STATE_1 and start
sending SABM(E).
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
net/lapb/lapb_iface.c | 74 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index 3c03f6512c5f..6a109c8c286f 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -418,14 +418,88 @@ int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *skb)
return used;
}
+/*
+ * Handle device status changes.
+ */
+static int lapb_device_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
+{
+ struct net_device *dev = ptr;
+ struct lapb_cb *lapb;
+
+ if (!net_eq(dev_net(dev), &init_net))
+ return NOTIFY_DONE;
+
+ if (dev->type == ARPHRD_X25) {
+ switch (event) {
+ case NETDEV_REGISTER:
+ lapb_dbg(0, "(%p): got event NETDEV_REGISTER for device: %s\n", dev, dev->name);
+ break;
+ case NETDEV_POST_TYPE_CHANGE:
+ lapb_dbg(0, "(%p): got event NETDEV_POST_TYPE_CHANGE for device: %s\n", dev, dev->name);
+ break;
+ case NETDEV_UP:
+ lapb_dbg(0, "(%p): got event NETDEV_UP for device: %s\n", dev, dev->name);
+ break;
+ case NETDEV_GOING_DOWN:
+ lapb_dbg(0, "(%p): got event NETDEV_GOING_DOWN for device: %s\n", dev, dev->name);
+ break;
+ case NETDEV_DOWN:
+ lapb_dbg(0, "(%p): got event NETDEV_DOWN for device: %s\n", dev, dev->name);
+ break;
+ case NETDEV_PRE_TYPE_CHANGE:
+ lapb_dbg(0, "(%p): got event NETDEV_PRE_TYPE_CHANGE for device: %s\n", dev, dev->name);
+ break;
+ case NETDEV_UNREGISTER:
+ lapb_dbg(0, "(%p): got event NETDEV_UNREGISTER for device: %s\n", dev, dev->name);
+ break;
+ case NETDEV_CHANGE:
+ lapb_dbg(0, "(%p): got event NETDEV_CHANGE for device: %s\n", dev, dev->name);
+ lapb = lapb_devtostruct(dev);
+ if (lapb) {
+ if (!netif_carrier_ok(dev)) {
+ lapb_dbg(0, "(%p): Carrier lost -> Entering LAPB_STATE_0: %s\n", dev, dev->name);
+ lapb_disconnect_indication(lapb, LAPB_OK);
+ lapb_clear_queues(lapb);
+ lapb->state = LAPB_STATE_0;
+ lapb->n2count = 0;
+ lapb_stop_t1timer(lapb);
+ lapb_stop_t2timer(lapb);
+ } else {
+ lapb_dbg(0, "(%p): Carrier detected: %s\n", dev, dev->name);
+ if (lapb->mode & LAPB_DCE) {
+ lapb_start_t1timer(lapb);
+ } else {
+ if (lapb->state == LAPB_STATE_0) {
+ lapb->state = LAPB_STATE_1;
+ lapb_establish_data_link(lapb);
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block lapb_dev_notifier = {
+ .notifier_call = lapb_device_event,
+};
+
static int __init lapb_init(void)
{
+ register_netdevice_notifier(&lapb_dev_notifier);
+
return 0;
}
static void __exit lapb_exit(void)
{
WARN_ON(!list_empty(&lapb_list));
+
+ unregister_netdevice_notifier(&lapb_dev_notifier);
}
MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/6] net/lapb: fix t1 timer handling
2020-11-16 7:31 [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Martin Schiller
` (3 preceding siblings ...)
2020-11-16 7:31 ` [PATCH 5/6] net/lapb: support netdev events Martin Schiller
@ 2020-11-16 7:31 ` Martin Schiller
2020-11-16 8:45 ` [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Xie He
5 siblings, 0 replies; 9+ messages in thread
From: Martin Schiller @ 2020-11-16 7:31 UTC (permalink / raw)
To: andrew.hendry, davem, kuba, xie.he.0141
Cc: linux-x25, netdev, linux-kernel, Martin Schiller
fix t1 timer handling in LAPB_STATE_0:
o DTE interface changes immediately to LAPB_STATE_1 and start sending
SABM(E).
o DCE interface sends N2-times DM and changes to LAPB_STATE_1
afterwards if there is no response in the meantime.
Signed-off-by: Martin Schiller <ms@dev.tdt.de>
---
net/lapb/lapb_timer.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/lapb/lapb_timer.c b/net/lapb/lapb_timer.c
index 8f5b17001a07..d1f80d67892f 100644
--- a/net/lapb/lapb_timer.c
+++ b/net/lapb/lapb_timer.c
@@ -85,11 +85,16 @@ static void lapb_t1timer_expiry(struct timer_list *t)
switch (lapb->state) {
/*
- * If we are a DCE, keep going DM .. DM .. DM
+ * If we are a DCE, send DM up to N2 times, then switch to STATE_1 and send SABM(E)
*/
case LAPB_STATE_0:
- if (lapb->mode & LAPB_DCE)
+ if (lapb->mode & LAPB_DCE && lapb->n2count != lapb->n2) {
+ lapb->n2count++;
lapb_send_control(lapb, LAPB_DM, LAPB_POLLOFF, LAPB_RESPONSE);
+ } else {
+ lapb->state = LAPB_STATE_1;
+ lapb_establish_data_link(lapb);
+ }
break;
/*
--
2.20.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER
2020-11-16 7:31 [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Martin Schiller
` (4 preceding siblings ...)
2020-11-16 7:31 ` [PATCH 6/6] net/lapb: fix t1 timer handling Martin Schiller
@ 2020-11-16 8:45 ` Xie He
2020-11-16 8:59 ` Martin Schiller
5 siblings, 1 reply; 9+ messages in thread
From: Xie He @ 2020-11-16 8:45 UTC (permalink / raw)
To: Martin Schiller
Cc: Andrew Hendry, David S. Miller, Jakub Kicinski, Linux X25,
Linux Kernel Network Developers, LKML
Hi Martin,
Thanks for the series. To get the series applied faster, could you
address the warnings and failures shown on this page?
https://patchwork.kernel.org/project/netdevbpf/list/?submitter=174539
Thanks!
To let the netdev robot know which tree this series should be applied,
we can use [PATCH net-next 1/6] as the subject prefix.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER
2020-11-16 8:45 ` [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Xie He
@ 2020-11-16 8:59 ` Martin Schiller
0 siblings, 0 replies; 9+ messages in thread
From: Martin Schiller @ 2020-11-16 8:59 UTC (permalink / raw)
To: Xie He
Cc: Andrew Hendry, David S. Miller, Jakub Kicinski, Linux X25,
Linux Kernel Network Developers, LKML
On 2020-11-16 09:45, Xie He wrote:
> Hi Martin,
>
> Thanks for the series. To get the series applied faster, could you
> address the warnings and failures shown on this page?
> https://patchwork.kernel.org/project/netdevbpf/list/?submitter=174539
> Thanks!
>
> To let the netdev robot know which tree this series should be applied,
> we can use [PATCH net-next 1/6] as the subject prefix.
Hi Xie!
Thanks. I will have a look at this.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/6] net/x25: make neighbour params configurable
2020-11-16 7:31 ` [PATCH 2/6] net/x25: make neighbour params configurable Martin Schiller
@ 2020-11-16 13:10 ` kernel test robot
0 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2020-11-16 13:10 UTC (permalink / raw)
To: Martin Schiller, andrew.hendry, davem, kuba, xie.he.0141
Cc: kbuild-all, clang-built-linux, linux-x25, netdev, linux-kernel,
Martin Schiller
[-- Attachment #1: Type: text/plain, Size: 6027 bytes --]
Hi Martin,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on net-next/master]
[also build test ERROR on net/master linus/master sparc-next/master v5.10-rc4 next-20201116]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Martin-Schiller/net-x25-add-remove-x25_link_device-by-NETDEV_REGISTER-UNREGISTER/20201116-153459
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 0064c5c1b3bf2a695c772c90e8dea38426a870ff
config: x86_64-randconfig-a011-20201116 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c044709b8fbea2a9a375e4173a6bd735f6866c0c)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/2d44533245f7e8388db93c53c26703ac52650e57
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Martin-Schiller/net-x25-add-remove-x25_link_device-by-NETDEV_REGISTER-UNREGISTER/20201116-153459
git checkout 2d44533245f7e8388db93c53c26703ac52650e57
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> net/x25/af_x25.c:1709:30: error: assigning to 'struct compat_x25_facilities' from incompatible type 'struct x25_facilities'
x25_subscr.facilities = nb->facilities;
^ ~~~~~~~~~~~~~~
>> net/x25/af_x25.c:1761:24: error: assigning to 'struct x25_facilities' from incompatible type 'struct compat_x25_facilities'
nb->facilities = x25_subscr.facilities;
^ ~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
vim +1709 net/x25/af_x25.c
1678
1679 #ifdef CONFIG_COMPAT
1680 static int compat_x25_subscr_ioctl(unsigned int cmd,
1681 struct compat_x25_subscrip_struct __user *x25_subscr32)
1682 {
1683 struct compat_x25_subscrip_struct x25_subscr;
1684 struct x25_neigh *nb;
1685 struct net_device *dev;
1686 int rc = -EINVAL;
1687
1688 if (cmd != SIOCX25GSUBSCRIP && cmd != SIOCX25SSUBSCRIP)
1689 goto out;
1690
1691 rc = -EFAULT;
1692 if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32)))
1693 goto out;
1694
1695 rc = -EINVAL;
1696 dev = x25_dev_get(x25_subscr.device);
1697 if (dev == NULL)
1698 goto out;
1699
1700 nb = x25_get_neigh(dev);
1701 if (nb == NULL)
1702 goto out_dev_put;
1703
1704 if (cmd == SIOCX25GSUBSCRIP) {
1705 read_lock_bh(&x25_neigh_list_lock);
1706 x25_subscr.extended = nb->extended;
1707 x25_subscr.dce = nb->dce;
1708 x25_subscr.lc = nb->lc;
> 1709 x25_subscr.facilities = nb->facilities;
1710 x25_subscr.t20 = nb->t20;
1711 x25_subscr.global_facil_mask = nb->global_facil_mask;
1712 read_unlock_bh(&x25_neigh_list_lock);
1713 rc = copy_to_user(x25_subscr32, &x25_subscr,
1714 sizeof(*x25_subscr32)) ? -EFAULT : 0;
1715 } else {
1716 rc = -EINVAL;
1717
1718 if (dev->flags & IFF_UP)
1719 return -EBUSY;
1720
1721 if (x25_subscr.extended != 0 && x25_subscr.extended != 1)
1722 goto out_dev_and_neigh_put;
1723 if (x25_subscr.dce != 0 && x25_subscr.dce != 1)
1724 goto out_dev_and_neigh_put;
1725 if (x25_subscr.lc < 1 || x25_subscr.lc > 4095)
1726 goto out_dev_and_neigh_put;
1727 if (x25_subscr.facilities.pacsize_in < X25_PS16 ||
1728 x25_subscr.facilities.pacsize_in > X25_PS4096)
1729 goto out_dev_and_neigh_put;
1730 if (x25_subscr.facilities.pacsize_out < X25_PS16 ||
1731 x25_subscr.facilities.pacsize_out > X25_PS4096)
1732 goto out_dev_and_neigh_put;
1733 if (x25_subscr.facilities.winsize_in < 1 ||
1734 x25_subscr.facilities.winsize_in > 127)
1735 goto out_dev_and_neigh_put;
1736 if (x25_subscr.facilities.throughput) {
1737 int out = x25_subscr.facilities.throughput & 0xf0;
1738 int in = x25_subscr.facilities.throughput & 0x0f;
1739 if (!out)
1740 x25_subscr.facilities.throughput |=
1741 X25_DEFAULT_THROUGHPUT << 4;
1742 else if (out < 0x30 || out > 0xD0)
1743 goto out_dev_and_neigh_put;
1744 if (!in)
1745 x25_subscr.facilities.throughput |=
1746 X25_DEFAULT_THROUGHPUT;
1747 else if (in < 0x03 || in > 0x0D)
1748 goto out_dev_and_neigh_put;
1749 }
1750 if (x25_subscr.facilities.reverse &&
1751 (x25_subscr.facilities.reverse & 0x81) != 0x81)
1752 goto out_dev_and_neigh_put;
1753 if (x25_subscr.t20 < 1 * HZ || x25_subscr.t20 > 300 * HZ)
1754 goto out_dev_and_neigh_put;
1755
1756 rc = 0;
1757 write_lock_bh(&x25_neigh_list_lock);
1758 nb->extended = x25_subscr.extended;
1759 nb->dce = x25_subscr.dce;
1760 nb->lc = x25_subscr.lc;
> 1761 nb->facilities = x25_subscr.facilities;
1762 nb->t20 = x25_subscr.t20;
1763 nb->global_facil_mask = x25_subscr.global_facil_mask;
1764 write_unlock_bh(&x25_neigh_list_lock);
1765 }
1766 dev_put(dev);
1767
1768 x25_neigh_put(nb);
1769 out:
1770 return rc;
1771 out_dev_and_neigh_put:
1772 x25_neigh_put(nb);
1773 out_dev_put:
1774 dev_put(dev);
1775 goto out;
1776 }
1777
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32127 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2020-11-16 13:11 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-16 7:31 [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Martin Schiller
2020-11-16 7:31 ` [PATCH 2/6] net/x25: make neighbour params configurable Martin Schiller
2020-11-16 13:10 ` kernel test robot
2020-11-16 7:31 ` [PATCH 3/6] net/x25: replace x25_kill_by_device with x25_kill_by_neigh Martin Schiller
2020-11-16 7:31 ` [PATCH 4/6] net/x25: support NETDEV_CHANGE notifier Martin Schiller
2020-11-16 7:31 ` [PATCH 5/6] net/lapb: support netdev events Martin Schiller
2020-11-16 7:31 ` [PATCH 6/6] net/lapb: fix t1 timer handling Martin Schiller
2020-11-16 8:45 ` [PATCH 1/6] net/x25: add/remove x25_link_device by NETDEV_REGISTER/UNREGISTER Xie He
2020-11-16 8:59 ` Martin Schiller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).