diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-22 13:56:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-22 13:56:23 -0500 |
commit | 36177ba655c238e33400cc2837a28720b62784bd (patch) | |
tree | c285738397f0272f1e0e973c5e6a53b2e8da74b1 | |
parent | 2152f8536668a957ea3214735b4761e7b22ef7d8 (diff) | |
parent | 056755f4d73d49b4adcbb8ecdaf75138cf166bd3 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
[TG3]: Bump driver version and reldate.
[TG3]: Skip phy power down on some devices
[TG3]: Fix SRAM access during tg3_init_one()
[X25]: dte facilities 32 64 ioctl conversion
[X25]: allow ITU-T DTE facilities for x25
[X25]: fix kernel error message 64 bit kernel
[X25]: ioctl conversion 32 bit user to 64 bit kernel
[NET]: socket timestamp 32 bit handler for 64 bit kernel
[NET]: allow 32 bit socket ioctl in 64 bit kernel
[BLUETOOTH]: Return negative error constant
-rw-r--r-- | drivers/net/tg3.c | 32 | ||||
-rw-r--r-- | include/linux/net.h | 6 | ||||
-rw-r--r-- | include/linux/x25.h | 26 | ||||
-rw-r--r-- | include/net/compat.h | 4 | ||||
-rw-r--r-- | include/net/x25.h | 21 | ||||
-rw-r--r-- | net/bluetooth/bnep/core.c | 4 | ||||
-rw-r--r-- | net/compat.c | 19 | ||||
-rw-r--r-- | net/socket.c | 21 | ||||
-rw-r--r-- | net/x25/af_x25.c | 173 | ||||
-rw-r--r-- | net/x25/x25_facilities.c | 82 | ||||
-rw-r--r-- | net/x25/x25_in.c | 3 | ||||
-rw-r--r-- | net/x25/x25_subr.c | 6 |
12 files changed, 366 insertions, 31 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e03d1ae50c3e..88829eb9568e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -69,8 +69,8 @@ | |||
69 | 69 | ||
70 | #define DRV_MODULE_NAME "tg3" | 70 | #define DRV_MODULE_NAME "tg3" |
71 | #define PFX DRV_MODULE_NAME ": " | 71 | #define PFX DRV_MODULE_NAME ": " |
72 | #define DRV_MODULE_VERSION "3.52" | 72 | #define DRV_MODULE_VERSION "3.53" |
73 | #define DRV_MODULE_RELDATE "Mar 06, 2006" | 73 | #define DRV_MODULE_RELDATE "Mar 22, 2006" |
74 | 74 | ||
75 | #define TG3_DEF_MAC_MODE 0 | 75 | #define TG3_DEF_MAC_MODE 0 |
76 | #define TG3_DEF_RX_MODE 0 | 76 | #define TG3_DEF_RX_MODE 0 |
@@ -1148,6 +1148,19 @@ static int tg3_halt_cpu(struct tg3 *, u32); | |||
1148 | static int tg3_nvram_lock(struct tg3 *); | 1148 | static int tg3_nvram_lock(struct tg3 *); |
1149 | static void tg3_nvram_unlock(struct tg3 *); | 1149 | static void tg3_nvram_unlock(struct tg3 *); |
1150 | 1150 | ||
1151 | static void tg3_power_down_phy(struct tg3 *tp) | ||
1152 | { | ||
1153 | /* The PHY should not be powered down on some chips because | ||
1154 | * of bugs. | ||
1155 | */ | ||
1156 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || | ||
1157 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 || | ||
1158 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 && | ||
1159 | (tp->tg3_flags2 & TG3_FLG2_MII_SERDES))) | ||
1160 | return; | ||
1161 | tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); | ||
1162 | } | ||
1163 | |||
1151 | static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | 1164 | static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) |
1152 | { | 1165 | { |
1153 | u32 misc_host_ctrl; | 1166 | u32 misc_host_ctrl; |
@@ -1327,8 +1340,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) | |||
1327 | tg3_writephy(tp, MII_TG3_EXT_CTRL, | 1340 | tg3_writephy(tp, MII_TG3_EXT_CTRL, |
1328 | MII_TG3_EXT_CTRL_FORCE_LED_OFF); | 1341 | MII_TG3_EXT_CTRL_FORCE_LED_OFF); |
1329 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); | 1342 | tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2); |
1330 | if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) | 1343 | tg3_power_down_phy(tp); |
1331 | tg3_writephy(tp, MII_BMCR, BMCR_PDOWN); | ||
1332 | } | 1344 | } |
1333 | } | 1345 | } |
1334 | 1346 | ||
@@ -9436,12 +9448,18 @@ static inline struct subsys_tbl_ent *lookup_by_subsys(struct tg3 *tp) | |||
9436 | return NULL; | 9448 | return NULL; |
9437 | } | 9449 | } |
9438 | 9450 | ||
9439 | /* Since this function may be called in D3-hot power state during | ||
9440 | * tg3_init_one(), only config cycles are allowed. | ||
9441 | */ | ||
9442 | static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | 9451 | static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) |
9443 | { | 9452 | { |
9444 | u32 val; | 9453 | u32 val; |
9454 | u16 pmcsr; | ||
9455 | |||
9456 | /* On some early chips the SRAM cannot be accessed in D3hot state, | ||
9457 | * so need make sure we're in D0. | ||
9458 | */ | ||
9459 | pci_read_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, &pmcsr); | ||
9460 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | ||
9461 | pci_write_config_word(tp->pdev, tp->pm_cap + PCI_PM_CTRL, pmcsr); | ||
9462 | msleep(1); | ||
9445 | 9463 | ||
9446 | /* Make sure register accesses (indirect or otherwise) | 9464 | /* Make sure register accesses (indirect or otherwise) |
9447 | * will function correctly. | 9465 | * will function correctly. |
diff --git a/include/linux/net.h b/include/linux/net.h index 152fa6551fd8..84a490e5f0a1 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -143,6 +143,8 @@ struct proto_ops { | |||
143 | struct poll_table_struct *wait); | 143 | struct poll_table_struct *wait); |
144 | int (*ioctl) (struct socket *sock, unsigned int cmd, | 144 | int (*ioctl) (struct socket *sock, unsigned int cmd, |
145 | unsigned long arg); | 145 | unsigned long arg); |
146 | int (*compat_ioctl) (struct socket *sock, unsigned int cmd, | ||
147 | unsigned long arg); | ||
146 | int (*listen) (struct socket *sock, int len); | 148 | int (*listen) (struct socket *sock, int len); |
147 | int (*shutdown) (struct socket *sock, int flags); | 149 | int (*shutdown) (struct socket *sock, int flags); |
148 | int (*setsockopt)(struct socket *sock, int level, | 150 | int (*setsockopt)(struct socket *sock, int level, |
@@ -251,6 +253,8 @@ SOCKCALL_UWRAP(name, poll, (struct file *file, struct socket *sock, struct poll_ | |||
251 | (file, sock, wait)) \ | 253 | (file, sock, wait)) \ |
252 | SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \ | 254 | SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \ |
253 | unsigned long arg), (sock, cmd, arg)) \ | 255 | unsigned long arg), (sock, cmd, arg)) \ |
256 | SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \ | ||
257 | unsigned long arg), (sock, cmd, arg)) \ | ||
254 | SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \ | 258 | SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \ |
255 | SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \ | 259 | SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \ |
256 | SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \ | 260 | SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \ |
@@ -275,6 +279,7 @@ static const struct proto_ops name##_ops = { \ | |||
275 | .getname = __lock_##name##_getname, \ | 279 | .getname = __lock_##name##_getname, \ |
276 | .poll = __lock_##name##_poll, \ | 280 | .poll = __lock_##name##_poll, \ |
277 | .ioctl = __lock_##name##_ioctl, \ | 281 | .ioctl = __lock_##name##_ioctl, \ |
282 | .compat_ioctl = __lock_##name##_compat_ioctl, \ | ||
278 | .listen = __lock_##name##_listen, \ | 283 | .listen = __lock_##name##_listen, \ |
279 | .shutdown = __lock_##name##_shutdown, \ | 284 | .shutdown = __lock_##name##_shutdown, \ |
280 | .setsockopt = __lock_##name##_setsockopt, \ | 285 | .setsockopt = __lock_##name##_setsockopt, \ |
@@ -283,6 +288,7 @@ static const struct proto_ops name##_ops = { \ | |||
283 | .recvmsg = __lock_##name##_recvmsg, \ | 288 | .recvmsg = __lock_##name##_recvmsg, \ |
284 | .mmap = __lock_##name##_mmap, \ | 289 | .mmap = __lock_##name##_mmap, \ |
285 | }; | 290 | }; |
291 | |||
286 | #endif | 292 | #endif |
287 | 293 | ||
288 | #define MODULE_ALIAS_NETPROTO(proto) \ | 294 | #define MODULE_ALIAS_NETPROTO(proto) \ |
diff --git a/include/linux/x25.h b/include/linux/x25.h index 16d44931afa0..d035e4e87d07 100644 --- a/include/linux/x25.h +++ b/include/linux/x25.h | |||
@@ -11,6 +11,8 @@ | |||
11 | #ifndef X25_KERNEL_H | 11 | #ifndef X25_KERNEL_H |
12 | #define X25_KERNEL_H | 12 | #define X25_KERNEL_H |
13 | 13 | ||
14 | #include <linux/types.h> | ||
15 | |||
14 | #define SIOCX25GSUBSCRIP (SIOCPROTOPRIVATE + 0) | 16 | #define SIOCX25GSUBSCRIP (SIOCPROTOPRIVATE + 0) |
15 | #define SIOCX25SSUBSCRIP (SIOCPROTOPRIVATE + 1) | 17 | #define SIOCX25SSUBSCRIP (SIOCPROTOPRIVATE + 1) |
16 | #define SIOCX25GFACILITIES (SIOCPROTOPRIVATE + 2) | 18 | #define SIOCX25GFACILITIES (SIOCPROTOPRIVATE + 2) |
@@ -21,6 +23,8 @@ | |||
21 | #define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7) | 23 | #define SIOCX25SCUDMATCHLEN (SIOCPROTOPRIVATE + 7) |
22 | #define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8) | 24 | #define SIOCX25CALLACCPTAPPRV (SIOCPROTOPRIVATE + 8) |
23 | #define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9) | 25 | #define SIOCX25SENDCALLACCPT (SIOCPROTOPRIVATE + 9) |
26 | #define SIOCX25GDTEFACILITIES (SIOCPROTOPRIVATE + 10) | ||
27 | #define SIOCX25SDTEFACILITIES (SIOCPROTOPRIVATE + 11) | ||
24 | 28 | ||
25 | /* | 29 | /* |
26 | * Values for {get,set}sockopt. | 30 | * Values for {get,set}sockopt. |
@@ -77,6 +81,8 @@ struct x25_subscrip_struct { | |||
77 | #define X25_MASK_PACKET_SIZE 0x04 | 81 | #define X25_MASK_PACKET_SIZE 0x04 |
78 | #define X25_MASK_WINDOW_SIZE 0x08 | 82 | #define X25_MASK_WINDOW_SIZE 0x08 |
79 | 83 | ||
84 | #define X25_MASK_CALLING_AE 0x10 | ||
85 | #define X25_MASK_CALLED_AE 0x20 | ||
80 | 86 | ||
81 | 87 | ||
82 | /* | 88 | /* |
@@ -99,6 +105,26 @@ struct x25_facilities { | |||
99 | }; | 105 | }; |
100 | 106 | ||
101 | /* | 107 | /* |
108 | * ITU DTE facilities | ||
109 | * Only the called and calling address | ||
110 | * extension are currently implemented. | ||
111 | * The rest are in place to avoid the struct | ||
112 | * changing size if someone needs them later | ||
113 | */ | ||
114 | |||
115 | struct x25_dte_facilities { | ||
116 | __u16 delay_cumul; | ||
117 | __u16 delay_target; | ||
118 | __u16 delay_max; | ||
119 | __u8 min_throughput; | ||
120 | __u8 expedited; | ||
121 | __u8 calling_len; | ||
122 | __u8 called_len; | ||
123 | __u8 calling_ae[20]; | ||
124 | __u8 called_ae[20]; | ||
125 | }; | ||
126 | |||
127 | /* | ||
102 | * Call User Data structure. | 128 | * Call User Data structure. |
103 | */ | 129 | */ |
104 | struct x25_calluserdata { | 130 | struct x25_calluserdata { |
diff --git a/include/net/compat.h b/include/net/compat.h index 290bab46d457..8662b8f43df5 100644 --- a/include/net/compat.h +++ b/include/net/compat.h | |||
@@ -23,6 +23,9 @@ struct compat_cmsghdr { | |||
23 | compat_int_t cmsg_type; | 23 | compat_int_t cmsg_type; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | struct sock; | ||
27 | extern int compat_sock_get_timestamp(struct sock *, struct timeval __user *); | ||
28 | |||
26 | #else /* defined(CONFIG_COMPAT) */ | 29 | #else /* defined(CONFIG_COMPAT) */ |
27 | #define compat_msghdr msghdr /* to avoid compiler warnings */ | 30 | #define compat_msghdr msghdr /* to avoid compiler warnings */ |
28 | #endif /* defined(CONFIG_COMPAT) */ | 31 | #endif /* defined(CONFIG_COMPAT) */ |
@@ -34,7 +37,6 @@ extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsi | |||
34 | extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); | 37 | extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); |
35 | extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); | 38 | extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); |
36 | 39 | ||
37 | struct sock; | ||
38 | extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int); | 40 | extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int); |
39 | 41 | ||
40 | #endif /* NET_COMPAT_H */ | 42 | #endif /* NET_COMPAT_H */ |
diff --git a/include/net/x25.h b/include/net/x25.h index fee62ff8c194..0ad90ebcf86e 100644 --- a/include/net/x25.h +++ b/include/net/x25.h | |||
@@ -101,9 +101,17 @@ enum { | |||
101 | #define X25_FAC_PACKET_SIZE 0x42 | 101 | #define X25_FAC_PACKET_SIZE 0x42 |
102 | #define X25_FAC_WINDOW_SIZE 0x43 | 102 | #define X25_FAC_WINDOW_SIZE 0x43 |
103 | 103 | ||
104 | #define X25_MAX_FAC_LEN 20 /* Plenty to spare */ | 104 | #define X25_MAX_FAC_LEN 60 |
105 | #define X25_MAX_CUD_LEN 128 | 105 | #define X25_MAX_CUD_LEN 128 |
106 | 106 | ||
107 | #define X25_FAC_CALLING_AE 0xCB | ||
108 | #define X25_FAC_CALLED_AE 0xC9 | ||
109 | |||
110 | #define X25_MARKER 0x00 | ||
111 | #define X25_DTE_SERVICES 0x0F | ||
112 | #define X25_MAX_AE_LEN 40 /* Max num of semi-octets in AE - OSI Nw */ | ||
113 | #define X25_MAX_DTE_FACIL_LEN 21 /* Max length of DTE facility params */ | ||
114 | |||
107 | /** | 115 | /** |
108 | * struct x25_route - x25 routing entry | 116 | * struct x25_route - x25 routing entry |
109 | * @node - entry in x25_list_lock | 117 | * @node - entry in x25_list_lock |
@@ -148,6 +156,7 @@ struct x25_sock { | |||
148 | struct timer_list timer; | 156 | struct timer_list timer; |
149 | struct x25_causediag causediag; | 157 | struct x25_causediag causediag; |
150 | struct x25_facilities facilities; | 158 | struct x25_facilities facilities; |
159 | struct x25_dte_facilities dte_facilities; | ||
151 | struct x25_calluserdata calluserdata; | 160 | struct x25_calluserdata calluserdata; |
152 | unsigned long vc_facil_mask; /* inc_call facilities mask */ | 161 | unsigned long vc_facil_mask; /* inc_call facilities mask */ |
153 | }; | 162 | }; |
@@ -180,9 +189,13 @@ extern void x25_establish_link(struct x25_neigh *); | |||
180 | extern void x25_terminate_link(struct x25_neigh *); | 189 | extern void x25_terminate_link(struct x25_neigh *); |
181 | 190 | ||
182 | /* x25_facilities.c */ | 191 | /* x25_facilities.c */ |
183 | extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, unsigned long *); | 192 | extern int x25_parse_facilities(struct sk_buff *, struct x25_facilities *, |
184 | extern int x25_create_facilities(unsigned char *, struct x25_facilities *, unsigned long); | 193 | struct x25_dte_facilities *, unsigned long *); |
185 | extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, struct x25_facilities *); | 194 | extern int x25_create_facilities(unsigned char *, struct x25_facilities *, |
195 | struct x25_dte_facilities *, unsigned long); | ||
196 | extern int x25_negotiate_facilities(struct sk_buff *, struct sock *, | ||
197 | struct x25_facilities *, | ||
198 | struct x25_dte_facilities *); | ||
186 | extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *); | 199 | extern void x25_limit_facilities(struct x25_facilities *, struct x25_neigh *); |
187 | 200 | ||
188 | /* x25_in.c */ | 201 | /* x25_in.c */ |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index cbb20c32a6c8..d908d49dc9f8 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -532,8 +532,8 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock) | |||
532 | dev = alloc_netdev(sizeof(struct bnep_session), | 532 | dev = alloc_netdev(sizeof(struct bnep_session), |
533 | (*req->device) ? req->device : "bnep%d", | 533 | (*req->device) ? req->device : "bnep%d", |
534 | bnep_net_setup); | 534 | bnep_net_setup); |
535 | if (!dev) | 535 | if (!dev) |
536 | return ENOMEM; | 536 | return -ENOMEM; |
537 | 537 | ||
538 | 538 | ||
539 | down_write(&bnep_session_sem); | 539 | down_write(&bnep_session_sem); |
diff --git a/net/compat.c b/net/compat.c index 13177a1a4b39..8fd37cd7b501 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -543,6 +543,25 @@ static int compat_sock_getsockopt(struct socket *sock, int level, int optname, | |||
543 | return sock_getsockopt(sock, level, optname, optval, optlen); | 543 | return sock_getsockopt(sock, level, optname, optval, optlen); |
544 | } | 544 | } |
545 | 545 | ||
546 | int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) | ||
547 | { | ||
548 | struct compat_timeval __user *ctv = | ||
549 | (struct compat_timeval __user*) userstamp; | ||
550 | int err = -ENOENT; | ||
551 | |||
552 | if (!sock_flag(sk, SOCK_TIMESTAMP)) | ||
553 | sock_enable_timestamp(sk); | ||
554 | if (sk->sk_stamp.tv_sec == -1) | ||
555 | return err; | ||
556 | if (sk->sk_stamp.tv_sec == 0) | ||
557 | do_gettimeofday(&sk->sk_stamp); | ||
558 | if (put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec) || | ||
559 | put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec)) | ||
560 | err = -EFAULT; | ||
561 | return err; | ||
562 | } | ||
563 | EXPORT_SYMBOL(compat_sock_get_timestamp); | ||
564 | |||
546 | asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, | 565 | asmlinkage long compat_sys_getsockopt(int fd, int level, int optname, |
547 | char __user *optval, int __user *optlen) | 566 | char __user *optval, int __user *optlen) |
548 | { | 567 | { |
diff --git a/net/socket.c b/net/socket.c index e3c21d5ec288..e2d5bae994de 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -107,6 +107,10 @@ static unsigned int sock_poll(struct file *file, | |||
107 | struct poll_table_struct *wait); | 107 | struct poll_table_struct *wait); |
108 | static long sock_ioctl(struct file *file, | 108 | static long sock_ioctl(struct file *file, |
109 | unsigned int cmd, unsigned long arg); | 109 | unsigned int cmd, unsigned long arg); |
110 | #ifdef CONFIG_COMPAT | ||
111 | static long compat_sock_ioctl(struct file *file, | ||
112 | unsigned int cmd, unsigned long arg); | ||
113 | #endif | ||
110 | static int sock_fasync(int fd, struct file *filp, int on); | 114 | static int sock_fasync(int fd, struct file *filp, int on); |
111 | static ssize_t sock_readv(struct file *file, const struct iovec *vector, | 115 | static ssize_t sock_readv(struct file *file, const struct iovec *vector, |
112 | unsigned long count, loff_t *ppos); | 116 | unsigned long count, loff_t *ppos); |
@@ -128,6 +132,9 @@ static struct file_operations socket_file_ops = { | |||
128 | .aio_write = sock_aio_write, | 132 | .aio_write = sock_aio_write, |
129 | .poll = sock_poll, | 133 | .poll = sock_poll, |
130 | .unlocked_ioctl = sock_ioctl, | 134 | .unlocked_ioctl = sock_ioctl, |
135 | #ifdef CONFIG_COMPAT | ||
136 | .compat_ioctl = compat_sock_ioctl, | ||
137 | #endif | ||
131 | .mmap = sock_mmap, | 138 | .mmap = sock_mmap, |
132 | .open = sock_no_open, /* special open code to disallow open via /proc */ | 139 | .open = sock_no_open, /* special open code to disallow open via /proc */ |
133 | .release = sock_close, | 140 | .release = sock_close, |
@@ -2136,6 +2143,20 @@ void socket_seq_show(struct seq_file *seq) | |||
2136 | } | 2143 | } |
2137 | #endif /* CONFIG_PROC_FS */ | 2144 | #endif /* CONFIG_PROC_FS */ |
2138 | 2145 | ||
2146 | #ifdef CONFIG_COMPAT | ||
2147 | static long compat_sock_ioctl(struct file *file, unsigned cmd, | ||
2148 | unsigned long arg) | ||
2149 | { | ||
2150 | struct socket *sock = file->private_data; | ||
2151 | int ret = -ENOIOCTLCMD; | ||
2152 | |||
2153 | if (sock->ops->compat_ioctl) | ||
2154 | ret = sock->ops->compat_ioctl(sock, cmd, arg); | ||
2155 | |||
2156 | return ret; | ||
2157 | } | ||
2158 | #endif | ||
2159 | |||
2139 | /* ABI emulation layers need these two */ | 2160 | /* ABI emulation layers need these two */ |
2140 | EXPORT_SYMBOL(move_addr_to_kernel); | 2161 | EXPORT_SYMBOL(move_addr_to_kernel); |
2141 | EXPORT_SYMBOL(move_addr_to_user); | 2162 | EXPORT_SYMBOL(move_addr_to_user); |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 72b6ff3299ba..282ce4e40d7b 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -54,7 +54,10 @@ | |||
54 | #include <linux/termios.h> /* For TIOCINQ/OUTQ */ | 54 | #include <linux/termios.h> /* For TIOCINQ/OUTQ */ |
55 | #include <linux/notifier.h> | 55 | #include <linux/notifier.h> |
56 | #include <linux/init.h> | 56 | #include <linux/init.h> |
57 | #include <linux/compat.h> | ||
58 | |||
57 | #include <net/x25.h> | 59 | #include <net/x25.h> |
60 | #include <net/compat.h> | ||
58 | 61 | ||
59 | int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20; | 62 | int sysctl_x25_restart_request_timeout = X25_DEFAULT_T20; |
60 | int sysctl_x25_call_request_timeout = X25_DEFAULT_T21; | 63 | int sysctl_x25_call_request_timeout = X25_DEFAULT_T21; |
@@ -69,6 +72,14 @@ static const struct proto_ops x25_proto_ops; | |||
69 | 72 | ||
70 | static struct x25_address null_x25_address = {" "}; | 73 | static struct x25_address null_x25_address = {" "}; |
71 | 74 | ||
75 | #ifdef CONFIG_COMPAT | ||
76 | struct compat_x25_subscrip_struct { | ||
77 | char device[200-sizeof(compat_ulong_t)]; | ||
78 | compat_ulong_t global_facil_mask; | ||
79 | compat_uint_t extended; | ||
80 | }; | ||
81 | #endif | ||
82 | |||
72 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, | 83 | int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr, |
73 | struct x25_address *calling_addr) | 84 | struct x25_address *calling_addr) |
74 | { | 85 | { |
@@ -514,6 +525,13 @@ static int x25_create(struct socket *sock, int protocol) | |||
514 | x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; | 525 | x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE; |
515 | x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; | 526 | x25->facilities.throughput = X25_DEFAULT_THROUGHPUT; |
516 | x25->facilities.reverse = X25_DEFAULT_REVERSE; | 527 | x25->facilities.reverse = X25_DEFAULT_REVERSE; |
528 | x25->dte_facilities.calling_len = 0; | ||
529 | x25->dte_facilities.called_len = 0; | ||
530 | memset(x25->dte_facilities.called_ae, '\0', | ||
531 | sizeof(x25->dte_facilities.called_ae)); | ||
532 | memset(x25->dte_facilities.calling_ae, '\0', | ||
533 | sizeof(x25->dte_facilities.calling_ae)); | ||
534 | |||
517 | rc = 0; | 535 | rc = 0; |
518 | out: | 536 | out: |
519 | return rc; | 537 | return rc; |
@@ -550,6 +568,7 @@ static struct sock *x25_make_new(struct sock *osk) | |||
550 | x25->t2 = ox25->t2; | 568 | x25->t2 = ox25->t2; |
551 | x25->facilities = ox25->facilities; | 569 | x25->facilities = ox25->facilities; |
552 | x25->qbitincl = ox25->qbitincl; | 570 | x25->qbitincl = ox25->qbitincl; |
571 | x25->dte_facilities = ox25->dte_facilities; | ||
553 | x25->cudmatchlength = ox25->cudmatchlength; | 572 | x25->cudmatchlength = ox25->cudmatchlength; |
554 | x25->accptapprv = ox25->accptapprv; | 573 | x25->accptapprv = ox25->accptapprv; |
555 | 574 | ||
@@ -733,7 +752,7 @@ out: | |||
733 | return rc; | 752 | return rc; |
734 | } | 753 | } |
735 | 754 | ||
736 | static int x25_wait_for_data(struct sock *sk, int timeout) | 755 | static int x25_wait_for_data(struct sock *sk, long timeout) |
737 | { | 756 | { |
738 | DECLARE_WAITQUEUE(wait, current); | 757 | DECLARE_WAITQUEUE(wait, current); |
739 | int rc = 0; | 758 | int rc = 0; |
@@ -829,6 +848,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, | |||
829 | struct x25_sock *makex25; | 848 | struct x25_sock *makex25; |
830 | struct x25_address source_addr, dest_addr; | 849 | struct x25_address source_addr, dest_addr; |
831 | struct x25_facilities facilities; | 850 | struct x25_facilities facilities; |
851 | struct x25_dte_facilities dte_facilities; | ||
832 | int len, rc; | 852 | int len, rc; |
833 | 853 | ||
834 | /* | 854 | /* |
@@ -865,7 +885,8 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, | |||
865 | /* | 885 | /* |
866 | * Try to reach a compromise on the requested facilities. | 886 | * Try to reach a compromise on the requested facilities. |
867 | */ | 887 | */ |
868 | if ((len = x25_negotiate_facilities(skb, sk, &facilities)) == -1) | 888 | len = x25_negotiate_facilities(skb, sk, &facilities, &dte_facilities); |
889 | if (len == -1) | ||
869 | goto out_sock_put; | 890 | goto out_sock_put; |
870 | 891 | ||
871 | /* | 892 | /* |
@@ -896,9 +917,12 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, | |||
896 | makex25->source_addr = source_addr; | 917 | makex25->source_addr = source_addr; |
897 | makex25->neighbour = nb; | 918 | makex25->neighbour = nb; |
898 | makex25->facilities = facilities; | 919 | makex25->facilities = facilities; |
920 | makex25->dte_facilities= dte_facilities; | ||
899 | makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask; | 921 | makex25->vc_facil_mask = x25_sk(sk)->vc_facil_mask; |
900 | /* ensure no reverse facil on accept */ | 922 | /* ensure no reverse facil on accept */ |
901 | makex25->vc_facil_mask &= ~X25_MASK_REVERSE; | 923 | makex25->vc_facil_mask &= ~X25_MASK_REVERSE; |
924 | /* ensure no calling address extension on accept */ | ||
925 | makex25->vc_facil_mask &= ~X25_MASK_CALLING_AE; | ||
902 | makex25->cudmatchlength = x25_sk(sk)->cudmatchlength; | 926 | makex25->cudmatchlength = x25_sk(sk)->cudmatchlength; |
903 | 927 | ||
904 | /* Normally all calls are accepted immediatly */ | 928 | /* Normally all calls are accepted immediatly */ |
@@ -1305,6 +1329,36 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1305 | break; | 1329 | break; |
1306 | } | 1330 | } |
1307 | 1331 | ||
1332 | case SIOCX25GDTEFACILITIES: { | ||
1333 | rc = copy_to_user(argp, &x25->dte_facilities, | ||
1334 | sizeof(x25->dte_facilities)); | ||
1335 | if (rc) | ||
1336 | rc = -EFAULT; | ||
1337 | break; | ||
1338 | } | ||
1339 | |||
1340 | case SIOCX25SDTEFACILITIES: { | ||
1341 | struct x25_dte_facilities dtefacs; | ||
1342 | rc = -EFAULT; | ||
1343 | if (copy_from_user(&dtefacs, argp, sizeof(dtefacs))) | ||
1344 | break; | ||
1345 | rc = -EINVAL; | ||
1346 | if (sk->sk_state != TCP_LISTEN && | ||
1347 | sk->sk_state != TCP_CLOSE) | ||
1348 | break; | ||
1349 | if (dtefacs.calling_len > X25_MAX_AE_LEN) | ||
1350 | break; | ||
1351 | if (dtefacs.calling_ae == NULL) | ||
1352 | break; | ||
1353 | if (dtefacs.called_len > X25_MAX_AE_LEN) | ||
1354 | break; | ||
1355 | if (dtefacs.called_ae == NULL) | ||
1356 | break; | ||
1357 | x25->dte_facilities = dtefacs; | ||
1358 | rc = 0; | ||
1359 | break; | ||
1360 | } | ||
1361 | |||
1308 | case SIOCX25GCALLUSERDATA: { | 1362 | case SIOCX25GCALLUSERDATA: { |
1309 | struct x25_calluserdata cud = x25->calluserdata; | 1363 | struct x25_calluserdata cud = x25->calluserdata; |
1310 | rc = copy_to_user(argp, &cud, | 1364 | rc = copy_to_user(argp, &cud, |
@@ -1387,6 +1441,118 @@ static struct net_proto_family x25_family_ops = { | |||
1387 | .owner = THIS_MODULE, | 1441 | .owner = THIS_MODULE, |
1388 | }; | 1442 | }; |
1389 | 1443 | ||
1444 | #ifdef CONFIG_COMPAT | ||
1445 | static int compat_x25_subscr_ioctl(unsigned int cmd, | ||
1446 | struct compat_x25_subscrip_struct __user *x25_subscr32) | ||
1447 | { | ||
1448 | struct compat_x25_subscrip_struct x25_subscr; | ||
1449 | struct x25_neigh *nb; | ||
1450 | struct net_device *dev; | ||
1451 | int rc = -EINVAL; | ||
1452 | |||
1453 | rc = -EFAULT; | ||
1454 | if (copy_from_user(&x25_subscr, x25_subscr32, sizeof(*x25_subscr32))) | ||
1455 | goto out; | ||
1456 | |||
1457 | rc = -EINVAL; | ||
1458 | dev = x25_dev_get(x25_subscr.device); | ||
1459 | if (dev == NULL) | ||
1460 | goto out; | ||
1461 | |||
1462 | nb = x25_get_neigh(dev); | ||
1463 | if (nb == NULL) | ||
1464 | goto out_dev_put; | ||
1465 | |||
1466 | dev_put(dev); | ||
1467 | |||
1468 | if (cmd == SIOCX25GSUBSCRIP) { | ||
1469 | x25_subscr.extended = nb->extended; | ||
1470 | x25_subscr.global_facil_mask = nb->global_facil_mask; | ||
1471 | rc = copy_to_user(x25_subscr32, &x25_subscr, | ||
1472 | sizeof(*x25_subscr32)) ? -EFAULT : 0; | ||
1473 | } else { | ||
1474 | rc = -EINVAL; | ||
1475 | if (x25_subscr.extended == 0 || x25_subscr.extended == 1) { | ||
1476 | rc = 0; | ||
1477 | nb->extended = x25_subscr.extended; | ||
1478 | nb->global_facil_mask = x25_subscr.global_facil_mask; | ||
1479 | } | ||
1480 | } | ||
1481 | x25_neigh_put(nb); | ||
1482 | out: | ||
1483 | return rc; | ||
1484 | out_dev_put: | ||
1485 | dev_put(dev); | ||
1486 | goto out; | ||
1487 | } | ||
1488 | |||
1489 | static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, | ||
1490 | unsigned long arg) | ||
1491 | { | ||
1492 | void __user *argp = compat_ptr(arg); | ||
1493 | struct sock *sk = sock->sk; | ||
1494 | |||
1495 | int rc = -ENOIOCTLCMD; | ||
1496 | |||
1497 | switch(cmd) { | ||
1498 | case TIOCOUTQ: | ||
1499 | case TIOCINQ: | ||
1500 | rc = x25_ioctl(sock, cmd, (unsigned long)argp); | ||
1501 | break; | ||
1502 | case SIOCGSTAMP: | ||
1503 | rc = -EINVAL; | ||
1504 | if (sk) | ||
1505 | rc = compat_sock_get_timestamp(sk, | ||
1506 | (struct timeval __user*)argp); | ||
1507 | break; | ||
1508 | case SIOCGIFADDR: | ||
1509 | case SIOCSIFADDR: | ||
1510 | case SIOCGIFDSTADDR: | ||
1511 | case SIOCSIFDSTADDR: | ||
1512 | case SIOCGIFBRDADDR: | ||
1513 | case SIOCSIFBRDADDR: | ||
1514 | case SIOCGIFNETMASK: | ||
1515 | case SIOCSIFNETMASK: | ||
1516 | case SIOCGIFMETRIC: | ||
1517 | case SIOCSIFMETRIC: | ||
1518 | rc = -EINVAL; | ||
1519 | break; | ||
1520 | case SIOCADDRT: | ||
1521 | case SIOCDELRT: | ||
1522 | rc = -EPERM; | ||
1523 | if (!capable(CAP_NET_ADMIN)) | ||
1524 | break; | ||
1525 | rc = x25_route_ioctl(cmd, argp); | ||
1526 | break; | ||
1527 | case SIOCX25GSUBSCRIP: | ||
1528 | rc = compat_x25_subscr_ioctl(cmd, argp); | ||
1529 | break; | ||
1530 | case SIOCX25SSUBSCRIP: | ||
1531 | rc = -EPERM; | ||
1532 | if (!capable(CAP_NET_ADMIN)) | ||
1533 | break; | ||
1534 | rc = compat_x25_subscr_ioctl(cmd, argp); | ||
1535 | break; | ||
1536 | case SIOCX25GFACILITIES: | ||
1537 | case SIOCX25SFACILITIES: | ||
1538 | case SIOCX25GDTEFACILITIES: | ||
1539 | case SIOCX25SDTEFACILITIES: | ||
1540 | case SIOCX25GCALLUSERDATA: | ||
1541 | case SIOCX25SCALLUSERDATA: | ||
1542 | case SIOCX25GCAUSEDIAG: | ||
1543 | case SIOCX25SCUDMATCHLEN: | ||
1544 | case SIOCX25CALLACCPTAPPRV: | ||
1545 | case SIOCX25SENDCALLACCPT: | ||
1546 | rc = x25_ioctl(sock, cmd, (unsigned long)argp); | ||
1547 | break; | ||
1548 | default: | ||
1549 | rc = -ENOIOCTLCMD; | ||
1550 | break; | ||
1551 | } | ||
1552 | return rc; | ||
1553 | } | ||
1554 | #endif | ||
1555 | |||
1390 | static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { | 1556 | static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { |
1391 | .family = AF_X25, | 1557 | .family = AF_X25, |
1392 | .owner = THIS_MODULE, | 1558 | .owner = THIS_MODULE, |
@@ -1398,6 +1564,9 @@ static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { | |||
1398 | .getname = x25_getname, | 1564 | .getname = x25_getname, |
1399 | .poll = datagram_poll, | 1565 | .poll = datagram_poll, |
1400 | .ioctl = x25_ioctl, | 1566 | .ioctl = x25_ioctl, |
1567 | #ifdef CONFIG_COMPAT | ||
1568 | .compat_ioctl = compat_x25_ioctl, | ||
1569 | #endif | ||
1401 | .listen = x25_listen, | 1570 | .listen = x25_listen, |
1402 | .shutdown = sock_no_shutdown, | 1571 | .shutdown = sock_no_shutdown, |
1403 | .setsockopt = x25_setsockopt, | 1572 | .setsockopt = x25_setsockopt, |
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 54278b962f4c..9f42b9c9de37 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
@@ -28,18 +28,28 @@ | |||
28 | #include <net/x25.h> | 28 | #include <net/x25.h> |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * Parse a set of facilities into the facilities structure. Unrecognised | 31 | * Parse a set of facilities into the facilities structures. Unrecognised |
32 | * facilities are written to the debug log file. | 32 | * facilities are written to the debug log file. |
33 | */ | 33 | */ |
34 | int x25_parse_facilities(struct sk_buff *skb, | 34 | int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, |
35 | struct x25_facilities *facilities, | 35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) |
36 | unsigned long *vc_fac_mask) | ||
37 | { | 36 | { |
38 | unsigned char *p = skb->data; | 37 | unsigned char *p = skb->data; |
39 | unsigned int len = *p++; | 38 | unsigned int len = *p++; |
40 | 39 | ||
41 | *vc_fac_mask = 0; | 40 | *vc_fac_mask = 0; |
42 | 41 | ||
42 | /* | ||
43 | * The kernel knows which facilities were set on an incoming call but | ||
44 | * currently this information is not available to userspace. Here we | ||
45 | * give userspace who read incoming call facilities 0 length to indicate | ||
46 | * it wasn't set. | ||
47 | */ | ||
48 | dte_facs->calling_len = 0; | ||
49 | dte_facs->called_len = 0; | ||
50 | memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae)); | ||
51 | memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae)); | ||
52 | |||
43 | while (len > 0) { | 53 | while (len > 0) { |
44 | switch (*p & X25_FAC_CLASS_MASK) { | 54 | switch (*p & X25_FAC_CLASS_MASK) { |
45 | case X25_FAC_CLASS_A: | 55 | case X25_FAC_CLASS_A: |
@@ -74,6 +84,8 @@ int x25_parse_facilities(struct sk_buff *skb, | |||
74 | facilities->throughput = p[1]; | 84 | facilities->throughput = p[1]; |
75 | *vc_fac_mask |= X25_MASK_THROUGHPUT; | 85 | *vc_fac_mask |= X25_MASK_THROUGHPUT; |
76 | break; | 86 | break; |
87 | case X25_MARKER: | ||
88 | break; | ||
77 | default: | 89 | default: |
78 | printk(KERN_DEBUG "X.25: unknown facility " | 90 | printk(KERN_DEBUG "X.25: unknown facility " |
79 | "%02X, value %02X\n", | 91 | "%02X, value %02X\n", |
@@ -112,11 +124,30 @@ int x25_parse_facilities(struct sk_buff *skb, | |||
112 | len -= 4; | 124 | len -= 4; |
113 | break; | 125 | break; |
114 | case X25_FAC_CLASS_D: | 126 | case X25_FAC_CLASS_D: |
115 | printk(KERN_DEBUG "X.25: unknown facility %02X, " | 127 | switch (*p) { |
116 | "length %d, values %02X, %02X, %02X, %02X\n", | 128 | case X25_FAC_CALLING_AE: |
117 | p[0], p[1], p[2], p[3], p[4], p[5]); | 129 | if (p[1] > X25_MAX_DTE_FACIL_LEN) |
130 | break; | ||
131 | dte_facs->calling_len = p[2]; | ||
132 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); | ||
133 | *vc_fac_mask |= X25_MASK_CALLING_AE; | ||
134 | break; | ||
135 | case X25_FAC_CALLED_AE: | ||
136 | if (p[1] > X25_MAX_DTE_FACIL_LEN) | ||
137 | break; | ||
138 | dte_facs->called_len = p[2]; | ||
139 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); | ||
140 | *vc_fac_mask |= X25_MASK_CALLED_AE; | ||
141 | break; | ||
142 | default: | ||
143 | printk(KERN_DEBUG "X.25: unknown facility %02X," | ||
144 | "length %d, values %02X, %02X, " | ||
145 | "%02X, %02X\n", | ||
146 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
147 | break; | ||
148 | } | ||
118 | len -= p[1] + 2; | 149 | len -= p[1] + 2; |
119 | p += p[1] + 2; | 150 | p += p[1] + 2; |
120 | break; | 151 | break; |
121 | } | 152 | } |
122 | } | 153 | } |
@@ -128,8 +159,8 @@ int x25_parse_facilities(struct sk_buff *skb, | |||
128 | * Create a set of facilities. | 159 | * Create a set of facilities. |
129 | */ | 160 | */ |
130 | int x25_create_facilities(unsigned char *buffer, | 161 | int x25_create_facilities(unsigned char *buffer, |
131 | struct x25_facilities *facilities, | 162 | struct x25_facilities *facilities, |
132 | unsigned long facil_mask) | 163 | struct x25_dte_facilities *dte_facs, unsigned long facil_mask) |
133 | { | 164 | { |
134 | unsigned char *p = buffer + 1; | 165 | unsigned char *p = buffer + 1; |
135 | int len; | 166 | int len; |
@@ -168,6 +199,33 @@ int x25_create_facilities(unsigned char *buffer, | |||
168 | *p++ = facilities->winsize_out ? : facilities->winsize_in; | 199 | *p++ = facilities->winsize_out ? : facilities->winsize_in; |
169 | } | 200 | } |
170 | 201 | ||
202 | if (facil_mask & (X25_MASK_CALLING_AE|X25_MASK_CALLED_AE)) { | ||
203 | *p++ = X25_MARKER; | ||
204 | *p++ = X25_DTE_SERVICES; | ||
205 | } | ||
206 | |||
207 | if (dte_facs->calling_len && (facil_mask & X25_MASK_CALLING_AE)) { | ||
208 | unsigned bytecount = (dte_facs->calling_len % 2) ? | ||
209 | dte_facs->calling_len / 2 + 1 : | ||
210 | dte_facs->calling_len / 2; | ||
211 | *p++ = X25_FAC_CALLING_AE; | ||
212 | *p++ = 1 + bytecount; | ||
213 | *p++ = dte_facs->calling_len; | ||
214 | memcpy(p, dte_facs->calling_ae, bytecount); | ||
215 | p += bytecount; | ||
216 | } | ||
217 | |||
218 | if (dte_facs->called_len && (facil_mask & X25_MASK_CALLED_AE)) { | ||
219 | unsigned bytecount = (dte_facs->called_len % 2) ? | ||
220 | dte_facs->called_len / 2 + 1 : | ||
221 | dte_facs->called_len / 2; | ||
222 | *p++ = X25_FAC_CALLED_AE; | ||
223 | *p++ = 1 + bytecount; | ||
224 | *p++ = dte_facs->called_len; | ||
225 | memcpy(p, dte_facs->called_ae, bytecount); | ||
226 | p+=bytecount; | ||
227 | } | ||
228 | |||
171 | len = p - buffer; | 229 | len = p - buffer; |
172 | buffer[0] = len - 1; | 230 | buffer[0] = len - 1; |
173 | 231 | ||
@@ -180,7 +238,7 @@ int x25_create_facilities(unsigned char *buffer, | |||
180 | * The only real problem is with reverse charging. | 238 | * The only real problem is with reverse charging. |
181 | */ | 239 | */ |
182 | int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | 240 | int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, |
183 | struct x25_facilities *new) | 241 | struct x25_facilities *new, struct x25_dte_facilities *dte) |
184 | { | 242 | { |
185 | struct x25_sock *x25 = x25_sk(sk); | 243 | struct x25_sock *x25 = x25_sk(sk); |
186 | struct x25_facilities *ours = &x25->facilities; | 244 | struct x25_facilities *ours = &x25->facilities; |
@@ -190,7 +248,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, | |||
190 | memset(&theirs, 0, sizeof(theirs)); | 248 | memset(&theirs, 0, sizeof(theirs)); |
191 | memcpy(new, ours, sizeof(*new)); | 249 | memcpy(new, ours, sizeof(*new)); |
192 | 250 | ||
193 | len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask); | 251 | len = x25_parse_facilities(skb, &theirs, dte, &x25->vc_facil_mask); |
194 | 252 | ||
195 | /* | 253 | /* |
196 | * They want reverse charging, we won't accept it. | 254 | * They want reverse charging, we won't accept it. |
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 26146874b839..eed50e10f09b 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
@@ -106,7 +106,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
106 | skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); | 106 | skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr)); |
107 | skb_pull(skb, | 107 | skb_pull(skb, |
108 | x25_parse_facilities(skb, &x25->facilities, | 108 | x25_parse_facilities(skb, &x25->facilities, |
109 | &x25->vc_facil_mask)); | 109 | &x25->dte_facilities, |
110 | &x25->vc_facil_mask)); | ||
110 | /* | 111 | /* |
111 | * Copy any Call User Data. | 112 | * Copy any Call User Data. |
112 | */ | 113 | */ |
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c index 8be9b8fbc24d..8d6220aa5d0f 100644 --- a/net/x25/x25_subr.c +++ b/net/x25/x25_subr.c | |||
@@ -190,8 +190,9 @@ void x25_write_internal(struct sock *sk, int frametype) | |||
190 | dptr = skb_put(skb, len); | 190 | dptr = skb_put(skb, len); |
191 | memcpy(dptr, addresses, len); | 191 | memcpy(dptr, addresses, len); |
192 | len = x25_create_facilities(facilities, | 192 | len = x25_create_facilities(facilities, |
193 | &x25->facilities, | 193 | &x25->facilities, |
194 | x25->neighbour->global_facil_mask); | 194 | &x25->dte_facilities, |
195 | x25->neighbour->global_facil_mask); | ||
195 | dptr = skb_put(skb, len); | 196 | dptr = skb_put(skb, len); |
196 | memcpy(dptr, facilities, len); | 197 | memcpy(dptr, facilities, len); |
197 | dptr = skb_put(skb, x25->calluserdata.cudlength); | 198 | dptr = skb_put(skb, x25->calluserdata.cudlength); |
@@ -206,6 +207,7 @@ void x25_write_internal(struct sock *sk, int frametype) | |||
206 | *dptr++ = 0x00; /* Address lengths */ | 207 | *dptr++ = 0x00; /* Address lengths */ |
207 | len = x25_create_facilities(facilities, | 208 | len = x25_create_facilities(facilities, |
208 | &x25->facilities, | 209 | &x25->facilities, |
210 | &x25->dte_facilities, | ||
209 | x25->vc_facil_mask); | 211 | x25->vc_facil_mask); |
210 | dptr = skb_put(skb, len); | 212 | dptr = skb_put(skb, len); |
211 | memcpy(dptr, facilities, len); | 213 | memcpy(dptr, facilities, len); |