aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/udp_media.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/udp_media.c')
-rw-r--r--net/tipc/udp_media.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index d63a911e7fe2..c9cf2be3674a 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -48,19 +48,12 @@
48#include <linux/tipc_netlink.h> 48#include <linux/tipc_netlink.h>
49#include "core.h" 49#include "core.h"
50#include "bearer.h" 50#include "bearer.h"
51#include "netlink.h"
51 52
52/* IANA assigned UDP port */ 53/* IANA assigned UDP port */
53#define UDP_PORT_DEFAULT 6118 54#define UDP_PORT_DEFAULT 6118
54 55
55#define UDP_MIN_HEADROOM 28 56#define UDP_MIN_HEADROOM 48
56
57static const struct nla_policy tipc_nl_udp_policy[TIPC_NLA_UDP_MAX + 1] = {
58 [TIPC_NLA_UDP_UNSPEC] = {.type = NLA_UNSPEC},
59 [TIPC_NLA_UDP_LOCAL] = {.type = NLA_BINARY,
60 .len = sizeof(struct sockaddr_storage)},
61 [TIPC_NLA_UDP_REMOTE] = {.type = NLA_BINARY,
62 .len = sizeof(struct sockaddr_storage)},
63};
64 57
65/** 58/**
66 * struct udp_media_addr - IP/UDP addressing information 59 * struct udp_media_addr - IP/UDP addressing information
@@ -181,6 +174,8 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
181 err = PTR_ERR(rt); 174 err = PTR_ERR(rt);
182 goto tx_error; 175 goto tx_error;
183 } 176 }
177
178 skb->dev = rt->dst.dev;
184 ttl = ip4_dst_hoplimit(&rt->dst); 179 ttl = ip4_dst_hoplimit(&rt->dst);
185 udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr, 180 udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
186 dst->ipv4.s_addr, 0, ttl, 0, src->udp_port, 181 dst->ipv4.s_addr, 0, ttl, 0, src->udp_port,
@@ -201,7 +196,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
201 ttl = ip6_dst_hoplimit(ndst); 196 ttl = ip6_dst_hoplimit(ndst);
202 err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb, 197 err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
203 ndst->dev, &src->ipv6, 198 ndst->dev, &src->ipv6,
204 &dst->ipv6, 0, ttl, src->udp_port, 199 &dst->ipv6, 0, ttl, 0, src->udp_port,
205 dst->udp_port, false); 200 dst->udp_port, false);
206#endif 201#endif
207 } 202 }
@@ -274,7 +269,7 @@ static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub,
274 struct udp_media_addr *remote) 269 struct udp_media_addr *remote)
275{ 270{
276 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1]; 271 struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
277 struct sockaddr_storage *sa_local, *sa_remote; 272 struct sockaddr_storage sa_local, sa_remote;
278 273
279 if (!attrs[TIPC_NLA_BEARER_UDP_OPTS]) 274 if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
280 goto err; 275 goto err;
@@ -283,41 +278,48 @@ static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub,
283 tipc_nl_udp_policy)) 278 tipc_nl_udp_policy))
284 goto err; 279 goto err;
285 if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) { 280 if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) {
286 sa_local = nla_data(opts[TIPC_NLA_UDP_LOCAL]); 281 nla_memcpy(&sa_local, opts[TIPC_NLA_UDP_LOCAL],
287 sa_remote = nla_data(opts[TIPC_NLA_UDP_REMOTE]); 282 sizeof(sa_local));
283 nla_memcpy(&sa_remote, opts[TIPC_NLA_UDP_REMOTE],
284 sizeof(sa_remote));
288 } else { 285 } else {
289err: 286err:
290 pr_err("Invalid UDP bearer configuration"); 287 pr_err("Invalid UDP bearer configuration");
291 return -EINVAL; 288 return -EINVAL;
292 } 289 }
293 if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET) { 290 if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET) {
294 struct sockaddr_in *ip4; 291 struct sockaddr_in *ip4;
295 292
296 ip4 = (struct sockaddr_in *)sa_local; 293 ip4 = (struct sockaddr_in *)&sa_local;
297 local->proto = htons(ETH_P_IP); 294 local->proto = htons(ETH_P_IP);
298 local->udp_port = ip4->sin_port; 295 local->udp_port = ip4->sin_port;
299 local->ipv4.s_addr = ip4->sin_addr.s_addr; 296 local->ipv4.s_addr = ip4->sin_addr.s_addr;
300 297
301 ip4 = (struct sockaddr_in *)sa_remote; 298 ip4 = (struct sockaddr_in *)&sa_remote;
302 remote->proto = htons(ETH_P_IP); 299 remote->proto = htons(ETH_P_IP);
303 remote->udp_port = ip4->sin_port; 300 remote->udp_port = ip4->sin_port;
304 remote->ipv4.s_addr = ip4->sin_addr.s_addr; 301 remote->ipv4.s_addr = ip4->sin_addr.s_addr;
305 return 0; 302 return 0;
306 303
307#if IS_ENABLED(CONFIG_IPV6) 304#if IS_ENABLED(CONFIG_IPV6)
308 } else if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET6) { 305 } else if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET6) {
306 int atype;
309 struct sockaddr_in6 *ip6; 307 struct sockaddr_in6 *ip6;
310 308
311 ip6 = (struct sockaddr_in6 *)sa_local; 309 ip6 = (struct sockaddr_in6 *)&sa_local;
310 atype = ipv6_addr_type(&ip6->sin6_addr);
311 if (__ipv6_addr_needs_scope_id(atype) && !ip6->sin6_scope_id)
312 return -EINVAL;
313
312 local->proto = htons(ETH_P_IPV6); 314 local->proto = htons(ETH_P_IPV6);
313 local->udp_port = ip6->sin6_port; 315 local->udp_port = ip6->sin6_port;
314 local->ipv6 = ip6->sin6_addr; 316 memcpy(&local->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
315 ub->ifindex = ip6->sin6_scope_id; 317 ub->ifindex = ip6->sin6_scope_id;
316 318
317 ip6 = (struct sockaddr_in6 *)sa_remote; 319 ip6 = (struct sockaddr_in6 *)&sa_remote;
318 remote->proto = htons(ETH_P_IPV6); 320 remote->proto = htons(ETH_P_IPV6);
319 remote->udp_port = ip6->sin6_port; 321 remote->udp_port = ip6->sin6_port;
320 remote->ipv6 = ip6->sin6_addr; 322 memcpy(&remote->ipv6, &ip6->sin6_addr, sizeof(struct in6_addr));
321 return 0; 323 return 0;
322#endif 324#endif
323 } 325 }