[PATCH iproute2 1/2] tipc: introduce bearer add for remoteip

2016-08-30 Thread Richard Alpe
Introduce the ability to add remote IP addresses to an existing UDP
bearer. On the kernel side, adding a "remoteip" to an existing bearer
puts the bearer in "replicast" mode where TIPC multicast messages are
send out to each configured remoteip using unicast. This is required
for TIPC UDP bearers to work in environments where IP multicast is
disabled.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvara...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
---
 man/man8/tipc-bearer.8 |  24 ++
 tipc/bearer.c  | 125 +
 2 files changed, 149 insertions(+)

diff --git a/man/man8/tipc-bearer.8 b/man/man8/tipc-bearer.8
index 488305a..32be64d 100644
--- a/man/man8/tipc-bearer.8
+++ b/man/man8/tipc-bearer.8
@@ -11,6 +11,11 @@ tipc-bearer \- show or modify TIPC bearers
 .in +8
 
 .ti -8
+.B tipc bearer add media udp name
+.IB "NAME " "remoteip " REMOTEIP
+.br
+
+.ti -8
 .B tipc bearer enable
 .RB "[ " domain
 .IR DOMAIN " ]"
@@ -196,6 +201,25 @@ IP is specified the
 .B udp
 bearer runs in point-to-point mode.
 
+Multiple
+.B remoteip
+addresses can be added via the
+.B bearer add
+command. Adding one or more unicast
+.B remoteip
+addresses to an existing
+.B udp
+bearer puts the bearer in replicast mode where IP
+multicast is emulated by sending multiple unicast messages to each configured
+.B remoteip.
+When a peer sees a TIPC discovery message from an unknown peer the peer address
+is automatically added to the
+.B remoteip
+(replicast) list, thus only one side of
+a link needs to be manually configured. A
+.B remoteip
+address cannot be added to a multicast bearer.
+
 .TP
 .BI "remoteport " REMOTEPORT
 .br
diff --git a/tipc/bearer.c b/tipc/bearer.c
index 05dabe6..a9fc1d2 100644
--- a/tipc/bearer.c
+++ b/tipc/bearer.c
@@ -222,6 +222,129 @@ static int nl_add_bearer_name(struct nlmsghdr *nlh, const 
struct cmd *cmd,
return -EINVAL;
 }
 
+static void cmd_bearer_add_udp_help(struct cmdl *cmdl, char *media)
+{
+   fprintf(stderr, "Usage: %s bearer add media %s name NAME remoteip 
REMOTEIP\n\n",
+   cmdl->argv[0], media);
+}
+
+static void cmd_bearer_add_help(struct cmdl *cmdl)
+{
+   fprintf(stderr, "Usage: %s bearer add media udp name NAME remoteip 
REMOTEIP\n",
+   cmdl->argv[0]);
+}
+
+static int udp_bearer_add(struct nlmsghdr *nlh, struct opt *opts,
+ struct cmdl *cmdl)
+{
+   int err;
+   struct opt *opt;
+   struct nlattr *opts_nest;
+   char *remport = "6118";
+
+   opts_nest = mnl_attr_nest_start(nlh, TIPC_NLA_BEARER_UDP_OPTS);
+
+   if ((opt = get_opt(opts, "remoteport")))
+   remport = opt->val;
+
+   if ((opt = get_opt(opts, "remoteip"))) {
+   char *ip = opt->val;
+   struct addrinfo *addr = NULL;
+   struct addrinfo hints = {
+   .ai_family = AF_UNSPEC,
+   .ai_socktype = SOCK_DGRAM
+   };
+
+   if ((err = getaddrinfo(ip, remport, , ))) {
+   fprintf(stderr, "UDP address error: %s\n",
+   gai_strerror(err));
+   freeaddrinfo(addr);
+   return err;
+   }
+
+   mnl_attr_put(nlh, TIPC_NLA_UDP_REMOTE, addr->ai_addrlen,
+   addr->ai_addr);
+   freeaddrinfo(addr);
+   } else {
+   fprintf(stderr, "error, missing remoteip\n");
+   return -EINVAL;
+   }
+   mnl_attr_nest_end(nlh, opts_nest);
+
+   return 0;
+}
+
+static int cmd_bearer_add_media(struct nlmsghdr *nlh, const struct cmd *cmd,
+   struct cmdl *cmdl, void *data)
+{
+   int err;
+   char *media;
+   char buf[MNL_SOCKET_BUFFER_SIZE];
+   struct opt *opt;
+   struct nlattr *attrs;
+   struct opt opts[] = {
+   { "remoteip",   NULL },
+   { "remoteport", NULL },
+   { "name",   NULL },
+   { "media",  NULL },
+   { NULL }
+   };
+   struct tipc_sup_media sup_media[] = {
+   { "udp","name", cmd_bearer_add_udp_help},
+   { NULL, },
+   };
+
+   /* Rewind optind to include media in the option list */
+   cmdl->optind--;
+   if (parse_opts(opts, cmdl) < 0)
+   return -EINVAL;
+
+   if (!(opt = get_opt(opts, "media"))) {
+   fprintf(stderr, "error, missing media value\n");
+   return -EINVAL;
+   }
+   

[PATCH iproute2 2/2] tipc: add the ability to get UDP bearer options

2016-08-30 Thread Richard Alpe
In this patch we introduce the ability to get UDP specific bearer
options such as remoteip, remoteport, localip and localport.

After some discussions on tipc-discussion on how to handle media
specific options we agreed to pass them after the media.

For media generic bearer options we already do:
$ tipc bearer get OPTION media MEDIA name|device NAME|DEVICE

For the UDP media specific bearer options we introduce in this path:
$ tipc bearer get media udp name NAME OPTION
such as
$ tipc bearer get media udp name NAME remoteip

This allows bash-completion to tab complete only appropriate options,
it makes more logical sense and it scales better. Even though it might
look a little different to the user.

In order to use the existing option parsing framework to do this we
add a flag (OPT_KEY) to the option parsing function.

If the UDP bearer has multiple remoteip addresses associated with it
(replicast) we handle the TIPC_NLA_UDP_MULTI_REMOTEIP flag and send
a TIPC_NL_UDP_GET_REMOTEIP query transparently to the user.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvara...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
---
 man/man8/tipc-bearer.8 |   5 +-
 tipc/bearer.c  | 272 +++--
 tipc/cmdl.c|  15 ++-
 tipc/cmdl.h|   7 ++
 tipc/link.c|   8 +-
 tipc/media.c   |   4 +-
 6 files changed, 271 insertions(+), 40 deletions(-)

diff --git a/man/man8/tipc-bearer.8 b/man/man8/tipc-bearer.8
index 32be64d..d95b1e1 100644
--- a/man/man8/tipc-bearer.8
+++ b/man/man8/tipc-bearer.8
@@ -73,7 +73,7 @@ tipc-bearer \- show or modify TIPC bearers
 
 .ti -8
 .B tipc bearer get
-.RB "{ " "priority" " | " tolerance " | " window " } " media
+.RB "[ " "priority" " | " tolerance " | " window " ] " media
 .br
 .RB "{ { " eth " | " ib " } " device
 .IR "DEVICE" " }"
@@ -81,7 +81,8 @@ tipc-bearer \- show or modify TIPC bearers
 .br
 .RB "{ " udp
 .B name
-.IR NAME " }"
+.IR NAME
+.RB "[ " "localip " "| " "localport " "| " "remoteip " "| " "remoteport " "] }"
 .br
 
 .ti -8
diff --git a/tipc/bearer.c b/tipc/bearer.c
index a9fc1d2..8729dad 100644
--- a/tipc/bearer.c
+++ b/tipc/bearer.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -26,6 +27,15 @@
 #include "msg.h"
 #include "bearer.h"
 
+#define UDP_PROP_IP 1
+#define UDP_PROP_PORT 2
+
+struct cb_data {
+   int attr;
+   int prop;
+   struct nlmsghdr *nlh;
+};
+
 static void _print_bearer_opts(void)
 {
fprintf(stderr,
@@ -57,14 +67,17 @@ static void cmd_bearer_enable_l2_help(struct cmdl *cmdl, 
char *media)
 static void cmd_bearer_enable_udp_help(struct cmdl *cmdl, char *media)
 {
fprintf(stderr,
-   "Usage: %s bearer enable media %s name NAME localip IP 
[OPTIONS]\n"
-   "\nOPTIONS\n"
+   "Usage: %s bearer enable [OPTIONS] media %s name NAME localip 
IP [UDP OPTIONS]\n\n",
+   cmdl->argv[0], media);
+   fprintf(stderr,
+   "OPTIONS\n"
" domain DOMAIN - Discovery domain\n"
-   " priority PRIORITY - Bearer priority\n"
+   " priority PRIORITY - Bearer priority\n\n");
+   fprintf(stderr,
+   "UDP OPTIONS\n"
" localport PORT- Local UDP port (default 6118)\n"
" remoteip IP   - Remote IP address\n"
-   " remoteport IP - Remote UDP port (default 6118)\n",
-   cmdl->argv[0], media);
+   " remoteport PORT   - Remote UDP port (default 6118)\n");
 }
 
 static int get_netid_cb(const struct nlmsghdr *nlh, void *data)
@@ -283,10 +296,10 @@ static int cmd_bearer_add_media(struct nlmsghdr *nlh, 
const struct cmd *cmd,
struct opt *opt;
struct nlattr *attrs;
struct opt opts[] = {
-   { "remoteip",   NULL },
-   { "remoteport", NULL },
-   { "name",   NULL },
-   { "media",  NULL },
+   { "remoteip",   OPT_KEYVAL, NULL },
+   { "remoteport", OPT_KEYVAL, NULL },
+   { "name",   OPT_KEYVAL, NULL },
+   { "media",  OPT_KEYVAL, NULL },
{ NULL }
};
struct tipc_sup_media sup_media[] = {
@@ -364,1

[PATCH net-next 4/7] tipc: introduce UDP replicast

2016-08-26 Thread Richard Alpe
This patch introduces UDP replicast. A concept where we emulate
multicast by sending multiple unicast messages to configured peers.

The purpose of replicast is mainly to be able to use TIPC in cloud
environments where IP multicast is disabled. Using replicas to unicast
multicast messages is costly as we have to copy each skb and send the
copies individually.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
---
 include/uapi/linux/tipc_netlink.h |   1 +
 net/tipc/bearer.c |  44 ++
 net/tipc/bearer.h |   1 +
 net/tipc/netlink.c|   5 ++
 net/tipc/udp_media.c  | 118 ++
 net/tipc/udp_media.h  |  44 ++
 6 files changed, 201 insertions(+), 12 deletions(-)
 create mode 100644 net/tipc/udp_media.h

diff --git a/include/uapi/linux/tipc_netlink.h 
b/include/uapi/linux/tipc_netlink.h
index bcb65ef..b15664c 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -60,6 +60,7 @@ enum {
TIPC_NL_MON_GET,
TIPC_NL_MON_PEER_GET,
TIPC_NL_PEER_REMOVE,
+   TIPC_NL_BEARER_ADD,
 
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 28056fa..d7b442d 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -42,6 +42,7 @@
 #include "monitor.h"
 #include "bcast.h"
 #include "netlink.h"
+#include "udp_media.h"
 
 #define MAX_ADDR_STR 60
 
@@ -897,6 +898,49 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct 
genl_info *info)
return 0;
 }
 
+int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info)
+{
+   int err;
+   char *name;
+   struct tipc_bearer *b;
+   struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
+   struct net *net = sock_net(skb->sk);
+
+   if (!info->attrs[TIPC_NLA_BEARER])
+   return -EINVAL;
+
+   err = nla_parse_nested(attrs, TIPC_NLA_BEARER_MAX,
+  info->attrs[TIPC_NLA_BEARER],
+  tipc_nl_bearer_policy);
+   if (err)
+   return err;
+
+   if (!attrs[TIPC_NLA_BEARER_NAME])
+   return -EINVAL;
+   name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
+
+   rtnl_lock();
+   b = tipc_bearer_find(net, name);
+   if (!b) {
+   rtnl_unlock();
+   return -EINVAL;
+   }
+
+#ifdef CONFIG_TIPC_MEDIA_UDP
+   if (attrs[TIPC_NLA_BEARER_UDP_OPTS]) {
+   err = tipc_udp_nl_bearer_add(b,
+attrs[TIPC_NLA_BEARER_UDP_OPTS]);
+   if (err) {
+   rtnl_unlock();
+   return err;
+   }
+   }
+#endif
+   rtnl_unlock();
+
+   return 0;
+}
+
 int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
 {
int err;
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 83a9abb..78892e2f 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -181,6 +181,7 @@ int tipc_nl_bearer_enable(struct sk_buff *skb, struct 
genl_info *info);
 int tipc_nl_bearer_dump(struct sk_buff *skb, struct netlink_callback *cb);
 int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info);
 
 int tipc_nl_media_dump(struct sk_buff *skb, struct netlink_callback *cb);
 int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 2718de6..3122f21 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -161,6 +161,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
.policy = tipc_nl_policy,
},
{
+   .cmd= TIPC_NL_BEARER_ADD,
+   .doit   = tipc_nl_bearer_add,
+   .policy = tipc_nl_policy,
+   },
+   {
.cmd= TIPC_NL_BEARER_SET,
.doit   = tipc_nl_bearer_set,
.policy = tipc_nl_policy,
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index b8ec1a1..6b938cc 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -49,6 +49,7 @@
 #include "core.h"
 #include "bearer.h"
 #include "netlink.h"
+#include "msg.h"
 
 /* IANA assigned UDP port */
 #define UDP_PORT_DEFAULT   6118
@@ -70,6 +71,13 @@ struct udp_media_addr {
};
 };
 
+/* struct udp_replicast - container for UDP remote addresses */
+struct udp_replicast {
+   struct udp_media_addr addr;
+   struct rcu_head rcu;
+   struct list_head list;
+};
+
 /**
  * struct udp_bearer - ip/udp bearer data structure
  * @bearer:associated generic tipc bearer
@@ -82,6 +90,7 @@ struct udp_bearer 

[PATCH net-next 3/7] tipc: refactor multicast ip check

2016-08-26 Thread Richard Alpe
Add a function to check if a tipc UDP media address is a multicast
address or not. This is a purely cosmetic change.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
---
 net/tipc/udp_media.c | 34 +++---
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 7033b4a..b8ec1a1 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -84,6 +84,17 @@ struct udp_bearer {
struct work_struct work;
 };
 
+static int tipc_udp_is_mcast_addr(struct udp_media_addr *addr)
+{
+   if (ntohs(addr->proto) == ETH_P_IP)
+   return ipv4_is_multicast(addr->ipv4.s_addr);
+#if IS_ENABLED(CONFIG_IPV6)
+   else
+   return ipv6_addr_is_multicast(>ipv6);
+#endif
+   return 0;
+}
+
 /* udp_media_addr_set - convert a ip/udp address to a TIPC media address */
 static void tipc_udp_media_addr_set(struct tipc_media_addr *addr,
struct udp_media_addr *ua)
@@ -91,15 +102,9 @@ static void tipc_udp_media_addr_set(struct tipc_media_addr 
*addr,
memset(addr, 0, sizeof(struct tipc_media_addr));
addr->media_id = TIPC_MEDIA_TYPE_UDP;
memcpy(addr->value, ua, sizeof(struct udp_media_addr));
-   if (ntohs(ua->proto) == ETH_P_IP) {
-   if (ipv4_is_multicast(ua->ipv4.s_addr))
-   addr->broadcast = 1;
-   } else if (ntohs(ua->proto) == ETH_P_IPV6) {
-   if (ipv6_addr_type(>ipv6) & IPV6_ADDR_MULTICAST)
-   addr->broadcast = 1;
-   } else {
-   pr_err("Invalid UDP media address\n");
-   }
+
+   if (tipc_udp_is_mcast_addr(ua))
+   addr->broadcast = 1;
 }
 
 /* tipc_udp_addr2str - convert ip/udp address to string */
@@ -255,15 +260,11 @@ static int enable_mcast(struct udp_bearer *ub, struct 
udp_media_addr *remote)
struct sock *sk = ub->ubsock->sk;
 
if (ntohs(remote->proto) == ETH_P_IP) {
-   if (!ipv4_is_multicast(remote->ipv4.s_addr))
-   return 0;
mreqn.imr_multiaddr = remote->ipv4;
mreqn.imr_ifindex = ub->ifindex;
err = ip_mc_join_group(sk, );
 #if IS_ENABLED(CONFIG_IPV6)
} else {
-   if (!ipv6_addr_is_multicast(>ipv6))
-   return 0;
err = ipv6_stub->ipv6_sock_mc_join(sk, ub->ifindex,
   >ipv6);
 #endif
@@ -408,8 +409,11 @@ static int tipc_udp_enable(struct net *net, struct 
tipc_bearer *b,
tuncfg.encap_destroy = NULL;
setup_udp_tunnel_sock(net, ub->ubsock, );
 
-   if (enable_mcast(ub, remote))
-   goto err;
+   if (tipc_udp_is_mcast_addr(remote)) {
+   if (enable_mcast(ub, remote))
+   goto err;
+   }
+
return 0;
 err:
kfree(ub);
-- 
2.1.4



[PATCH net-next 1/7] tipc: split UDP nl address parsing

2016-08-26 Thread Richard Alpe
Split the UDP netlink parse function so that it only parses one
netlink attribute at the time. This makes the parse function more
generic and allow future UDP API functions to use it for parsing.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Ying Xue <ying@windriver.com>
---
 net/tipc/udp_media.c | 112 +--
 1 file changed, 55 insertions(+), 57 deletions(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 33bdf54..adb3c21 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -258,68 +258,47 @@ static int enable_mcast(struct udp_bearer *ub, struct 
udp_media_addr *remote)
 }
 
 /**
- * parse_options - build local/remote addresses from configuration
- * @attrs: netlink config data
- * @ub:UDP bearer instance
- * @local: local bearer IP address/port
- * @remote:peer or multicast IP/port
+ * tipc_parse_udp_addr - build udp media address from netlink data
+ * @nlattr:netlink attribute containing sockaddr storage aligned address
+ * @addr:  tipc media address to fill with address, port and protocol type
+ * @scope_id:  IPv6 scope id pointer, not NULL indicates it's required
  */
-static int parse_options(struct nlattr *attrs[], struct udp_bearer *ub,
-struct udp_media_addr *local,
-struct udp_media_addr *remote)
+
+static int tipc_parse_udp_addr(struct nlattr *nla, struct udp_media_addr *addr,
+  u32 *scope_id)
 {
-   struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
-   struct sockaddr_storage sa_local, sa_remote;
+   struct sockaddr_storage sa;
 
-   if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
-   goto err;
-   if (nla_parse_nested(opts, TIPC_NLA_UDP_MAX,
-attrs[TIPC_NLA_BEARER_UDP_OPTS],
-tipc_nl_udp_policy))
-   goto err;
-   if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) {
-   nla_memcpy(_local, opts[TIPC_NLA_UDP_LOCAL],
-  sizeof(sa_local));
-   nla_memcpy(_remote, opts[TIPC_NLA_UDP_REMOTE],
-  sizeof(sa_remote));
-   } else {
-err:
-   pr_err("Invalid UDP bearer configuration");
-   return -EINVAL;
-   }
-   if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET) {
-   struct sockaddr_in *ip4;
-
-   ip4 = (struct sockaddr_in *)_local;
-   local->proto = htons(ETH_P_IP);
-   local->port = ip4->sin_port;
-   local->ipv4.s_addr = ip4->sin_addr.s_addr;
-
-   ip4 = (struct sockaddr_in *)_remote;
-   remote->proto = htons(ETH_P_IP);
-   remote->port = ip4->sin_port;
-   remote->ipv4.s_addr = ip4->sin_addr.s_addr;
+   nla_memcpy(, nla, sizeof(sa));
+   if (sa.ss_family == AF_INET) {
+   struct sockaddr_in *ip4 = (struct sockaddr_in *)
+
+   addr->proto = htons(ETH_P_IP);
+   addr->port = ip4->sin_port;
+   addr->ipv4.s_addr = ip4->sin_addr.s_addr;
return 0;
 
 #if IS_ENABLED(CONFIG_IPV6)
-   } else if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET6) {
-   int atype;
-   struct sockaddr_in6 *ip6;
-
-   ip6 = (struct sockaddr_in6 *)_local;
-   atype = ipv6_addr_type(>sin6_addr);
-   if (__ipv6_addr_needs_scope_id(atype) && !ip6->sin6_scope_id)
-   return -EINVAL;
-
-   local->proto = htons(ETH_P_IPV6);
-   local->port = ip6->sin6_port;
-   memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
-   ub->ifindex = ip6->sin6_scope_id;
-
-   ip6 = (struct sockaddr_in6 *)_remote;
-   remote->proto = htons(ETH_P_IPV6);
-   remote->port = ip6->sin6_port;
-   memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
+   } else if (sa.ss_family == AF_INET6) {
+   struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *)
+
+   addr->proto = htons(ETH_P_IPV6);
+   addr->port = ip6->sin6_port;
+   memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
+
+   /* Scope ID is only interesting for local addresses */
+   if (scope_id) {
+   int atype;
+
+   atype = ipv6_addr_type(>sin6_addr);
+   if (__ipv6_addr_needs_scope_id(atype) &&
+   !ip6->sin6_scope_id) {
+   return -EINVAL;
+   }
+
+   *scope_id = ip6->sin6_scope_id ? : 

[PATCH net-next 0/7] tipc: introduce UDP replicast

2016-08-26 Thread Richard Alpe
This series introduces UDP replicast. A concept where we emulate multicast by
sending multiple unicast messages to configured peers. This allows TIPC to be
used in environments where IP multicast is disabled.

There is a corresponding patch series for the tipc user space tool that
allows a user to add remote addresses to the replicast list.

Richard Alpe (7):
  tipc: split UDP nl address parsing
  tipc: split UDP send function
  tipc: refactor multicast ip check
  tipc: introduce UDP replicast
  tipc: add replicast peer discovery
  tipc: add the ability to get UDP options via netlink
  tipc: add UDP remoteip dump to netlink API

 include/uapi/linux/tipc_netlink.h |   3 +
 net/tipc/bearer.c |  52 
 net/tipc/bearer.h |   1 +
 net/tipc/netlink.c|  15 +-
 net/tipc/udp_media.c  | 520 +++---
 net/tipc/udp_media.h  |  46 
 6 files changed, 545 insertions(+), 92 deletions(-)
 create mode 100644 net/tipc/udp_media.h

-- 
2.1.4



[PATCH net-next 6/7] tipc: add the ability to get UDP options via netlink

2016-08-26 Thread Richard Alpe
Add UDP bearer options to netlink bearer get message. This is used by
the tipc user space tool to display UDP options.

The UDP bearer information is passed using either a sockaddr_in or
sockaddr_in6 structs. This means the user space receiver should
intermediately store the retrieved data in a large enough struct
(sockaddr_strage) before casting to the proper IP version type.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Ying Xue <ying@windriver.com>
---
 include/uapi/linux/tipc_netlink.h |  2 ++
 net/tipc/bearer.c |  8 +
 net/tipc/udp_media.c  | 61 +++
 net/tipc/udp_media.h  |  1 +
 4 files changed, 72 insertions(+)

diff --git a/include/uapi/linux/tipc_netlink.h 
b/include/uapi/linux/tipc_netlink.h
index b15664c..f9edd20 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -61,6 +61,7 @@ enum {
TIPC_NL_MON_PEER_GET,
TIPC_NL_PEER_REMOVE,
TIPC_NL_BEARER_ADD,
+   TIPC_NL_UDP_GET_REMOTEIP,
 
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -100,6 +101,7 @@ enum {
TIPC_NLA_UDP_UNSPEC,
TIPC_NLA_UDP_LOCAL, /* sockaddr_storage */
TIPC_NLA_UDP_REMOTE,/* sockaddr_storage */
+   TIPC_NLA_UDP_MULTI_REMOTEIP,/* flag */
 
__TIPC_NLA_UDP_MAX,
TIPC_NLA_UDP_MAX = __TIPC_NLA_UDP_MAX - 1
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index d7b442d..975dbeb 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -712,6 +712,14 @@ static int __tipc_nl_add_bearer(struct tipc_nl_msg *msg,
goto prop_msg_full;
 
nla_nest_end(msg->skb, prop);
+
+#ifdef CONFIG_TIPC_MEDIA_UDP
+   if (bearer->media->type_id == TIPC_MEDIA_TYPE_UDP) {
+   if (tipc_udp_nl_add_bearer_data(msg, bearer))
+   goto attr_msg_full;
+   }
+#endif
+
nla_nest_end(msg->skb, attrs);
genlmsg_end(msg->skb, hdr);
 
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 6ece3c9..a6cdd98 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -401,6 +401,67 @@ static int enable_mcast(struct udp_bearer *ub, struct 
udp_media_addr *remote)
return err;
 }
 
+static int __tipc_nl_add_udp_addr(struct sk_buff *skb,
+ struct udp_media_addr *addr, int nla_t)
+{
+   if (ntohs(addr->proto) == ETH_P_IP) {
+   struct sockaddr_in ip4;
+
+   ip4.sin_family = AF_INET;
+   ip4.sin_port = addr->port;
+   ip4.sin_addr.s_addr = addr->ipv4.s_addr;
+   if (nla_put(skb, nla_t, sizeof(ip4), ))
+   return -EMSGSIZE;
+
+#if IS_ENABLED(CONFIG_IPV6)
+   } else if (ntohs(addr->proto) == ETH_P_IPV6) {
+   struct sockaddr_in6 ip6;
+
+   ip6.sin6_family = AF_INET6;
+   ip6.sin6_port  = addr->port;
+   memcpy(_addr, >ipv6, sizeof(struct in6_addr));
+   if (nla_put(skb, nla_t, sizeof(ip6), ))
+   return -EMSGSIZE;
+#endif
+   }
+
+   return 0;
+}
+
+int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b)
+{
+   struct udp_media_addr *src = (struct udp_media_addr *)>addr.value;
+   struct udp_media_addr *dst;
+   struct udp_bearer *ub;
+   struct nlattr *nest;
+
+   ub = rcu_dereference_rtnl(b->media_ptr);
+   if (!ub)
+   return -ENODEV;
+
+   nest = nla_nest_start(msg->skb, TIPC_NLA_BEARER_UDP_OPTS);
+   if (!nest)
+   goto msg_full;
+
+   if (__tipc_nl_add_udp_addr(msg->skb, src, TIPC_NLA_UDP_LOCAL))
+   goto msg_full;
+
+   dst = (struct udp_media_addr *)>bcast_addr.value;
+   if (__tipc_nl_add_udp_addr(msg->skb, dst, TIPC_NLA_UDP_REMOTE))
+   goto msg_full;
+
+   if (!list_empty(>rcast.list)) {
+   if (nla_put_flag(msg->skb, TIPC_NLA_UDP_MULTI_REMOTEIP))
+   goto msg_full;
+   }
+
+   nla_nest_end(msg->skb, nest);
+   return 0;
+msg_full:
+   nla_nest_cancel(msg->skb, nest);
+   return -EMSGSIZE;
+}
+
 /**
  * tipc_parse_udp_addr - build udp media address from netlink data
  * @nlattr:netlink attribute containing sockaddr storage aligned address
diff --git a/net/tipc/udp_media.h b/net/tipc/udp_media.h
index 4dcb548..c06326a 100644
--- a/net/tipc/udp_media.h
+++ b/net/tipc/udp_media.h
@@ -39,6 +39,7 @@
 #define _TIPC_UDP_MEDIA_H
 
 int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct nlattr *attr);
+int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer 
*b);
 
 #endif
 #endif
-- 
2.1.4



[PATCH net-next 2/7] tipc: split UDP send function

2016-08-26 Thread Richard Alpe
Split the UDP send function into two. One callback that prepares the
skb and one transmit function that sends the skb. This will come in
handy in later patches, when we introduce UDP replicast.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Ying Xue <ying@windriver.com>
---
 net/tipc/udp_media.c | 50 --
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index adb3c21..7033b4a 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -140,28 +140,13 @@ static int tipc_udp_addr2msg(char *msg, struct 
tipc_media_addr *a)
 }
 
 /* tipc_send_msg - enqueue a send request */
-static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
-struct tipc_bearer *b,
-struct tipc_media_addr *dest)
+static int tipc_udp_xmit(struct net *net, struct sk_buff *skb,
+struct udp_bearer *ub, struct udp_media_addr *src,
+struct udp_media_addr *dst)
 {
int ttl, err = 0;
-   struct udp_bearer *ub;
-   struct udp_media_addr *dst = (struct udp_media_addr *)>value;
-   struct udp_media_addr *src = (struct udp_media_addr *)>addr.value;
struct rtable *rt;
 
-   if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
-   err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
-   if (err)
-   goto tx_error;
-   }
-
-   skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
-   ub = rcu_dereference_rtnl(b->media_ptr);
-   if (!ub) {
-   err = -ENODEV;
-   goto tx_error;
-   }
if (dst->proto == htons(ETH_P_IP)) {
struct flowi4 fl = {
.daddr = dst->ipv4.s_addr,
@@ -207,6 +192,35 @@ tx_error:
return err;
 }
 
+static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
+struct tipc_bearer *b,
+struct tipc_media_addr *addr)
+{
+   struct udp_media_addr *src = (struct udp_media_addr *)>addr.value;
+   struct udp_media_addr *dst = (struct udp_media_addr *)>value;
+   struct udp_bearer *ub;
+   int err = 0;
+
+   if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
+   err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
+   if (err)
+   goto tx_error;
+   }
+
+   skb_set_inner_protocol(skb, htons(ETH_P_TIPC));
+   ub = rcu_dereference_rtnl(b->media_ptr);
+   if (!ub) {
+   err = -ENODEV;
+   goto tx_error;
+   }
+
+   return tipc_udp_xmit(net, skb, ub, src, dst);
+
+tx_error:
+   kfree_skb(skb);
+   return err;
+}
+
 /* tipc_udp_recv - read data from bearer socket */
 static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
 {
-- 
2.1.4



[PATCH net-next 7/7] tipc: add UDP remoteip dump to netlink API

2016-08-26 Thread Richard Alpe
When using replicast a UDP bearer can have an arbitrary amount of
remote ip addresses associated with it. This means we cannot simply
add all remote ip addresses to an existing bearer data message as it
might fill the message, leaving us with a truncated message that we
can't safely resume. To handle this we introduce the new netlink
command TIPC_NL_UDP_GET_REMOTEIP. This command is intended to be
called when the bearer data message has the
TIPC_NLA_UDP_MULTI_REMOTEIP flag set, indicating there are more than
one remote ip (replicast).

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
---
 net/tipc/netlink.c   | 10 +-
 net/tipc/udp_media.c | 90 
 net/tipc/udp_media.h |  1 +
 3 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 3122f21..3200059 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -41,6 +41,7 @@
 #include "link.h"
 #include "node.h"
 #include "net.h"
+#include "udp_media.h"
 #include 
 
 static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
@@ -247,7 +248,14 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
.cmd= TIPC_NL_PEER_REMOVE,
.doit   = tipc_nl_peer_rm,
.policy = tipc_nl_policy,
-   }
+   },
+#ifdef CONFIG_TIPC_MEDIA_UDP
+   {
+   .cmd= TIPC_NL_UDP_GET_REMOTEIP,
+   .dumpit = tipc_udp_nl_dump_remoteip,
+   .policy = tipc_nl_policy,
+   },
+#endif
 };
 
 int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index a6cdd98..245e9a2 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -428,6 +428,96 @@ static int __tipc_nl_add_udp_addr(struct sk_buff *skb,
return 0;
 }
 
+int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb)
+{
+   u32 bid = cb->args[0];
+   u32 skip_cnt = cb->args[1];
+   u32 portid = NETLINK_CB(cb->skb).portid;
+   struct udp_replicast *rcast, *tmp;
+   struct tipc_bearer *b;
+   struct udp_bearer *ub;
+   void *hdr;
+   int err;
+   int i;
+
+   if (!bid && !skip_cnt) {
+   struct net *net = sock_net(skb->sk);
+   struct nlattr *battrs[TIPC_NLA_BEARER_MAX + 1];
+   struct nlattr **attrs;
+   char *bname;
+
+   err = tipc_nlmsg_parse(cb->nlh, );
+   if (err)
+   return err;
+
+   if (!attrs[TIPC_NLA_BEARER])
+   return -EINVAL;
+
+   err = nla_parse_nested(battrs, TIPC_NLA_BEARER_MAX,
+  attrs[TIPC_NLA_BEARER],
+  tipc_nl_bearer_policy);
+   if (err)
+   return err;
+
+   if (!battrs[TIPC_NLA_BEARER_NAME])
+   return -EINVAL;
+
+   bname = nla_data(battrs[TIPC_NLA_BEARER_NAME]);
+
+   rtnl_lock();
+   b = tipc_bearer_find(net, bname);
+   if (!b) {
+   rtnl_unlock();
+   return -EINVAL;
+   }
+   bid = b->identity;
+   } else {
+   struct net *net = sock_net(skb->sk);
+   struct tipc_net *tn = net_generic(net, tipc_net_id);
+
+   rtnl_lock();
+   b = rtnl_dereference(tn->bearer_list[bid]);
+   if (!b) {
+   rtnl_unlock();
+   return -EINVAL;
+   }
+   }
+
+   ub = rcu_dereference_rtnl(b->media_ptr);
+   if (!ub) {
+   rtnl_unlock();
+   return -EINVAL;
+   }
+
+   i = 0;
+   list_for_each_entry_safe(rcast, tmp, >rcast.list, list) {
+   if (i < skip_cnt)
+   goto count;
+
+   hdr = genlmsg_put(skb, portid, cb->nlh->nlmsg_seq,
+ _genl_family, NLM_F_MULTI,
+ TIPC_NL_BEARER_GET);
+   if (!hdr)
+   goto done;
+
+   err = __tipc_nl_add_udp_addr(skb, >addr,
+TIPC_NLA_UDP_REMOTE);
+   if (err) {
+   genlmsg_cancel(skb, hdr);
+   goto done;
+   }
+   genlmsg_end(skb, hdr);
+count:
+   i++;
+   }
+done:
+   rtnl_unlock();
+   cb->args[0] = bid;
+   cb->args[1] = i;
+
+   return skb->len;
+}
+
 int tipc_udp_nl_add_bearer_data(struct tipc_nl_msg *msg, struct tipc_bearer *b)
 {
struct udp_media_addr *src = (struct udp_media_addr *)>addr.value;
diff --git a/net/tipc/udp_

[PATCH net-next 5/7] tipc: add replicast peer discovery

2016-08-26 Thread Richard Alpe
Automatically learn UDP remote IP addresses of communicating peers by
looking at the source IP address of incoming TIPC link configuration
messages (neighbor discovery).

This makes configuration slightly easier and removes the problematic
scenario where a node receives directly addressed neighbor discovery
messages sent using replicast which the node cannot "reply" to using
mutlicast, leaving the link FSM in a limbo state.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
---
 net/tipc/udp_media.c | 83 ++--
 1 file changed, 80 insertions(+), 3 deletions(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 6b938cc..6ece3c9 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -254,6 +254,26 @@ out:
return err;
 }
 
+static bool tipc_udp_is_known_peer(struct tipc_bearer *b,
+  struct udp_media_addr *addr)
+{
+   struct udp_replicast *rcast, *tmp;
+   struct udp_bearer *ub;
+
+   ub = rcu_dereference_rtnl(b->media_ptr);
+   if (!ub) {
+   pr_err_ratelimited("UDP bearer instance not found\n");
+   return false;
+   }
+
+   list_for_each_entry_safe(rcast, tmp, >rcast.list, list) {
+   if (!memcmp(>addr, addr, sizeof(struct udp_media_addr)))
+   return true;
+   }
+
+   return false;
+}
+
 static int tipc_udp_rcast_add(struct tipc_bearer *b,
  struct udp_media_addr *addr)
 {
@@ -281,29 +301,83 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
return 0;
 }
 
+static int tipc_udp_rcast_disc(struct tipc_bearer *b, struct sk_buff *skb)
+{
+   struct udp_media_addr src = {0};
+   struct udp_media_addr *dst;
+
+   dst = (struct udp_media_addr *)>bcast_addr.value;
+   if (tipc_udp_is_mcast_addr(dst))
+   return 0;
+
+   src.port = udp_hdr(skb)->source;
+
+   if (ip_hdr(skb)->version == 4) {
+   struct iphdr *iphdr = ip_hdr(skb);
+
+   src.proto = htons(ETH_P_IP);
+   src.ipv4.s_addr = iphdr->saddr;
+   if (ipv4_is_multicast(iphdr->daddr))
+   return 0;
+#if IS_ENABLED(CONFIG_IPV6)
+   } else if (ip_hdr(skb)->version == 6) {
+   struct ipv6hdr *iphdr = ipv6_hdr(skb);
+
+   src.proto = htons(ETH_P_IPV6);
+   src.ipv6 = iphdr->saddr;
+   if (ipv6_addr_is_multicast(>daddr))
+   return 0;
+#endif
+   } else {
+   return 0;
+   }
+
+   if (likely(tipc_udp_is_known_peer(b, )))
+   return 0;
+
+   return tipc_udp_rcast_add(b, );
+}
+
 /* tipc_udp_recv - read data from bearer socket */
 static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb)
 {
struct udp_bearer *ub;
struct tipc_bearer *b;
+   struct tipc_msg *hdr;
+   int err;
 
ub = rcu_dereference_sk_user_data(sk);
if (!ub) {
pr_err_ratelimited("Failed to get UDP bearer reference");
-   kfree_skb(skb);
-   return 0;
+   goto out;
}
-
skb_pull(skb, sizeof(struct udphdr));
+   hdr = buf_msg(skb);
+
rcu_read_lock();
b = rcu_dereference_rtnl(ub->bearer);
+   if (!b)
+   goto rcu_out;
 
if (b && test_bit(0, >up)) {
tipc_rcv(sock_net(sk), skb, b);
rcu_read_unlock();
return 0;
}
+
+   if (unlikely(msg_user(hdr) == LINK_CONFIG)) {
+   err = tipc_udp_rcast_disc(b, skb);
+   if (err)
+   goto rcu_out;
+   }
+
+   tipc_rcv(sock_net(sk), skb, b);
rcu_read_unlock();
+   return 0;
+
+rcu_out:
+   rcu_read_unlock();
+out:
kfree_skb(skb);
return 0;
 }
@@ -398,6 +472,9 @@ int tipc_udp_nl_bearer_add(struct tipc_bearer *b, struct 
nlattr *attr)
return -EINVAL;
}
 
+   if (tipc_udp_is_known_peer(b, ))
+   return 0;
+
return tipc_udp_rcast_add(b, );
 }
 
-- 
2.1.4



[PATCH iproute2] tipc: add peer remove functionality

2016-08-22 Thread Richard Alpe
This enables a user to remove an offline peer from the kernel data
structures. This could for example be useful when deliberately scaling
in peer nodes in a cloud environment.

This functionality was first merged in:
f9dec657e4 (Richard Alpe tipc: add peer remove functionality)

And later backed out (as the kernel counterpart was held up) in:
385caeb13b (Stephen Hemminger Revert "tipc: add peer remove functionality")

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Reviewed-by: Ying Xue <ying@windriver.com>
---
 include/linux/tipc_netlink.h |  1 +
 man/man8/tipc-bearer.8   |  1 +
 man/man8/tipc-link.8 |  1 +
 man/man8/tipc-media.8|  1 +
 man/man8/tipc-nametable.8|  1 +
 man/man8/tipc-node.8 |  1 +
 man/man8/tipc-peer.8 | 52 +
 man/man8/tipc.8  |  1 +
 tipc/Makefile|  2 +-
 tipc/peer.c  | 93 
 tipc/peer.h  | 21 ++
 tipc/tipc.c  |  3 ++
 12 files changed, 177 insertions(+), 1 deletion(-)
 create mode 100644 man/man8/tipc-peer.8
 create mode 100644 tipc/peer.c
 create mode 100644 tipc/peer.h

diff --git a/include/linux/tipc_netlink.h b/include/linux/tipc_netlink.h
index 5f3f6d0..bcb65ef 100644
--- a/include/linux/tipc_netlink.h
+++ b/include/linux/tipc_netlink.h
@@ -59,6 +59,7 @@ enum {
TIPC_NL_MON_SET,
TIPC_NL_MON_GET,
TIPC_NL_MON_PEER_GET,
+   TIPC_NL_PEER_REMOVE,
 
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/man/man8/tipc-bearer.8 b/man/man8/tipc-bearer.8
index 50a1ed2..565ee01 100644
--- a/man/man8/tipc-bearer.8
+++ b/man/man8/tipc-bearer.8
@@ -218,6 +218,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-media (8),
 .BR tipc-nametable (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-link.8 b/man/man8/tipc-link.8
index 3be8c9a..2ee03a0 100644
--- a/man/man8/tipc-link.8
+++ b/man/man8/tipc-link.8
@@ -213,6 +213,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-bearer (8),
 .BR tipc-nametable (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-media.8 b/man/man8/tipc-media.8
index 6c6e2b1..4689cb3 100644
--- a/man/man8/tipc-media.8
+++ b/man/man8/tipc-media.8
@@ -74,6 +74,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-link (8),
 .BR tipc-nametable (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-nametable.8 b/man/man8/tipc-nametable.8
index d3397f9..4bcefe4 100644
--- a/man/man8/tipc-nametable.8
+++ b/man/man8/tipc-nametable.8
@@ -87,6 +87,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-link (8),
 .BR tipc-media (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-node.8 b/man/man8/tipc-node.8
index ef32ec7..a72a409 100644
--- a/man/man8/tipc-node.8
+++ b/man/man8/tipc-node.8
@@ -59,6 +59,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-link (8),
 .BR tipc-media (8),
 .BR tipc-nametable (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-peer.8 b/man/man8/tipc-peer.8
new file mode 100644
index 000..430651f
--- /dev/null
+++ b/man/man8/tipc-peer.8
@@ -0,0 +1,52 @@
+.TH TIPC-PEER 8 "04 Dec 2015" "iproute2" "Linux"
+
+.\" For consistency, please keep padding right aligned.
+.\" For example '.B "foo " bar' and not '.B foo " bar"'
+
+.SH NAME
+tipc-peer \- modify peer information
+
+.SH SYNOPSIS
+.ad l
+.in +8
+
+.ti -8
+.B tipc peer remove address
+.IR ADDRESS
+
+.SH OPTIONS
+Options (flags) that can be passed anywhere in the command chain.
+.TP
+.BR "\-h" , " --help"
+Show help about last valid command. For example
+.B tipc peer --help
+will show peer help and
+.B tipc --help
+will show general help. The position of the option in the string is irrelevant.
+.SH DESCRIPTION
+
+.SS Peer remove
+Remove an offline peer node from the local data structures. The peer is
+identified by its
+.B address
+
+.SH EXIT STATUS
+Exit status is 0 if command was successful or a positive integer upon failure.
+
+.SH SEE ALSO
+.BR tipc (8),
+.BR tipc-bearer (8),
+.BR tipc-link (8),
+.BR tipc-media (8),
+.BR tipc-nametable (8),
+.BR tipc-node (8),
+.BR tipc-socket (8)
+.br
+.SH REPORTING BUGS
+Report any bugs to the Network Developers mailing list
+.B <netdev@vger.kernel.org>
+where the development and maintenance is primarily done.
+You do not have to be subscr

[PATCH net-next v3] tipc: add peer removal functionality

2016-08-18 Thread Richard Alpe
Add TIPC_NL_PEER_REMOVE netlink command. This command can remove
an offline peer node from the internal data structures.

This will be supported by the tipc user space tool in iproute2.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Ying Xue <ying@windriver.com>
---
 include/uapi/linux/tipc_netlink.h |  1 +
 net/tipc/net.h|  2 ++
 net/tipc/netlink.c|  5 
 net/tipc/node.c   | 63 +++
 net/tipc/node.h   |  1 +
 5 files changed, 72 insertions(+)

diff --git a/include/uapi/linux/tipc_netlink.h 
b/include/uapi/linux/tipc_netlink.h
index 5f3f6d0..bcb65ef 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -59,6 +59,7 @@ enum {
TIPC_NL_MON_SET,
TIPC_NL_MON_GET,
TIPC_NL_MON_PEER_GET,
+   TIPC_NL_PEER_REMOVE,
 
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 77a7a11..c7c2549 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -39,6 +39,8 @@
 
 #include 
 
+extern const struct nla_policy tipc_nl_net_policy[];
+
 int tipc_net_start(struct net *net, u32 addr);
 
 void tipc_net_stop(struct net *net);
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index a84daec..2718de6 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -238,6 +238,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
.dumpit = tipc_nl_node_dump_monitor_peer,
.policy = tipc_nl_policy,
},
+   {
+   .cmd= TIPC_NL_PEER_REMOVE,
+   .doit   = tipc_nl_peer_rm,
+   .policy = tipc_nl_policy,
+   }
 };
 
 int tipc_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr ***attr)
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 2197419..7e8b75f 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1553,6 +1553,69 @@ discard:
kfree_skb(skb);
 }
 
+int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
+{
+   struct net *net = sock_net(skb->sk);
+   struct tipc_net *tn = net_generic(net, tipc_net_id);
+   struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
+   struct tipc_node *peer;
+   u32 addr;
+   int err;
+   int i;
+
+   /* We identify the peer by its net */
+   if (!info->attrs[TIPC_NLA_NET])
+   return -EINVAL;
+
+   err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX,
+  info->attrs[TIPC_NLA_NET],
+  tipc_nl_net_policy);
+   if (err)
+   return err;
+
+   if (!attrs[TIPC_NLA_NET_ADDR])
+   return -EINVAL;
+
+   addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
+
+   if (in_own_node(net, addr))
+   return -ENOTSUPP;
+
+   spin_lock_bh(>node_list_lock);
+   peer = tipc_node_find(net, addr);
+   if (!peer) {
+   spin_unlock_bh(>node_list_lock);
+   return -ENXIO;
+   }
+
+   tipc_node_write_lock(peer);
+   if (peer->state != SELF_DOWN_PEER_DOWN &&
+   peer->state != SELF_DOWN_PEER_LEAVING) {
+   tipc_node_write_unlock(peer);
+   err = -EBUSY;
+   goto err_out;
+   }
+
+   for (i = 0; i < MAX_BEARERS; i++) {
+   struct tipc_link_entry *le = >links[i];
+
+   if (le->link) {
+   kfree(le->link);
+   le->link = NULL;
+   peer->link_cnt--;
+   }
+   }
+   tipc_node_write_unlock(peer);
+   tipc_node_delete(peer);
+
+   err = 0;
+err_out:
+   tipc_node_put(peer);
+   spin_unlock_bh(>node_list_lock);
+
+   return err;
+}
+
 int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
int err;
diff --git a/net/tipc/node.h b/net/tipc/node.h
index d69fdfc..4578b34 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -77,6 +77,7 @@ int tipc_nl_node_dump_link(struct sk_buff *skb, struct 
netlink_callback *cb);
 int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info);
 
 int tipc_nl_node_set_monitor(struct sk_buff *skb, struct genl_info *info);
 int tipc_nl_node_get_monitor(struct sk_buff *skb, struct genl_info *info);
-- 
2.1.4



[PATCH iproute2 v2 2/2] tipc: refactor bearer identification

2016-08-15 Thread Richard Alpe
Introduce a generic function (nl_add_bearer_name()) that identifies a
bearer and adds it to an existing netlink message. This reduces code
complexity and makes the code a little bit easier to maintain.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 tipc/bearer.c | 313 --
 tipc/cmdl.h   |   6 ++
 2 files changed, 114 insertions(+), 205 deletions(-)

diff --git a/tipc/bearer.c b/tipc/bearer.c
index 30b54d9..05dabe6 100644
--- a/tipc/bearer.c
+++ b/tipc/bearer.c
@@ -29,7 +29,7 @@
 static void _print_bearer_opts(void)
 {
fprintf(stderr,
-   "\nOPTIONS\n"
+   "OPTIONS\n"
" priority  - Bearer link priority\n"
" tolerance - Bearer link tolerance\n"
" window- Bearer link window\n");
@@ -44,43 +44,27 @@ static void _print_bearer_media(void)
" eth   - Ethernet\n");
 }
 
-static void cmd_bearer_enable_l2_help(struct cmdl *cmdl)
+static void cmd_bearer_enable_l2_help(struct cmdl *cmdl, char *media)
 {
fprintf(stderr,
-   "Usage: %s bearer enable media MEDIA device DEVICE [OPTIONS]\n"
+   "Usage: %s bearer enable media %s device DEVICE [OPTIONS]\n"
"\nOPTIONS\n"
" domain DOMAIN - Discovery domain\n"
" priority PRIORITY - Bearer priority\n",
-   cmdl->argv[0]);
+   cmdl->argv[0], media);
 }
 
-static void cmd_bearer_enable_udp_help(struct cmdl *cmdl)
+static void cmd_bearer_enable_udp_help(struct cmdl *cmdl, char *media)
 {
fprintf(stderr,
-   "Usage: %s bearer enable media udp name NAME localip IP 
[OPTIONS]\n"
+   "Usage: %s bearer enable media %s name NAME localip IP 
[OPTIONS]\n"
"\nOPTIONS\n"
" domain DOMAIN - Discovery domain\n"
" priority PRIORITY - Bearer priority\n"
" localport PORT- Local UDP port (default 6118)\n"
" remoteip IP   - Remote IP address\n"
" remoteport IP - Remote UDP port (default 6118)\n",
-   cmdl->argv[0]);
-}
-
-static int enable_l2_bearer(struct nlmsghdr *nlh, struct opt *opts,
-   struct cmdl *cmdl)
-{
-   struct opt *opt;
-   char id[TIPC_MAX_BEARER_NAME];
-
-   if (!(opt = get_opt(opts, "device"))) {
-   fprintf(stderr, "error: missing bearer device\n");
-   return -EINVAL;
-   }
-   snprintf(id, sizeof(id), "eth:%s", opt->val);
-   mnl_attr_put_strz(nlh, TIPC_NLA_BEARER_NAME, id);
-
-   return 0;
+   cmdl->argv[0], media);
 }
 
 static int get_netid_cb(const struct nlmsghdr *nlh, void *data)
@@ -123,8 +107,8 @@ static int generate_multicast(short af, char *buf, int 
bufsize)
return 0;
 }
 
-static int enable_udp_bearer(struct nlmsghdr *nlh, struct opt *opts,
-struct cmdl *cmdl)
+static int nl_add_udp_enable_opts(struct nlmsghdr *nlh, struct opt *opts,
+ struct cmdl *cmdl)
 {
int err;
struct opt *opt;
@@ -134,7 +118,6 @@ static int enable_udp_bearer(struct nlmsghdr *nlh, struct 
opt *opts,
char *remport = "6118";
char *locip = NULL;
char *remip = NULL;
-   char name[TIPC_MAX_BEARER_NAME];
struct addrinfo *loc = NULL;
struct addrinfo *rem = NULL;
struct addrinfo hints = {
@@ -142,22 +125,9 @@ static int enable_udp_bearer(struct nlmsghdr *nlh, struct 
opt *opts,
.ai_socktype = SOCK_DGRAM
};
 
-   if (help_flag) {
-   cmd_bearer_enable_udp_help(cmdl);
-   /* TODO find a better error code? */
-   return -EINVAL;
-   }
-
-   if (!(opt = get_opt(opts, "name"))) {
-   fprintf(stderr, "error, udp bearer name missing\n");
-   cmd_bearer_enable_udp_help(cmdl);
-   return -EINVAL;
-   }
-   snprintf(name, sizeof(name), "udp:%s", opt->val);
-
if (!(opt = get_opt(opts, "localip"))) {
fprintf(stderr, "error, udp bearer localip missing\n");
-   cmd_bearer_enable_udp_help(cmdl);
+   cmd_bearer_enable_udp_help(cmdl, "udp");
return -EINVAL;
}
locip = opt->val;
@@ -197,8 +167,6 @@ static int enable_udp_bearer(struct nlmsghdr *nlh, struct 
opt *opts,
return -EINVAL;
}
 
-   mnl_attr_put_strz(nlh, TIPC_NLA_BEARER_NAME, name);
-
nest =

[PATCH iproute2 v2 1/2] tipc: fix UDP bearer synopsis

2016-08-15 Thread Richard Alpe
Local ip is not required to identify a UDP bearer and shouldn't be
passed to bearer disable, set or get. In this patch we remove the
localip entry from the synopsis of these functions.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 man/man8/tipc-bearer.8 | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/man/man8/tipc-bearer.8 b/man/man8/tipc-bearer.8
index 50a1ed2..846f1db 100644
--- a/man/man8/tipc-bearer.8
+++ b/man/man8/tipc-bearer.8
@@ -39,14 +39,12 @@ tipc-bearer \- show or modify TIPC bearers
 .B tipc bearer disable media
 .br
 .RB "{ { " eth " | " ib " } " device
-.IR DEVICE
+.IR "DEVICE " }
 .RB "|"
 .br
 .RB "{ " udp
 .B name
-.IR NAME
-.B localip
-.IR LOCALIP " } }"
+.IR NAME " }"
 .br
 
 .ti -8
@@ -65,9 +63,7 @@ tipc-bearer \- show or modify TIPC bearers
 .br
 .RB "{ " udp
 .B name
-.IR NAME
-.B localip
-.IR LOCALIP " } }"
+.IR NAME " }"
 .br
 
 .ti -8
@@ -80,9 +76,7 @@ tipc-bearer \- show or modify TIPC bearers
 .br
 .RB "{ " udp
 .B name
-.IR NAME
-.B localip
-.IR LOCALIP " } }"
+.IR NAME " }"
 .br
 
 .ti -8
-- 
2.1.4



[PATCH iproute2 1/2] tipc: fix UDP bearer synopsis

2016-08-09 Thread Richard Alpe
Local ip is not required to identify a UDP bearer and shouldn't be
passed to bearer disable, set or get. In this patch we remove the
localip entry from the synopsis of these functions.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 man/man8/tipc-bearer.8 | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/man/man8/tipc-bearer.8 b/man/man8/tipc-bearer.8
index 50a1ed2..846f1db 100644
--- a/man/man8/tipc-bearer.8
+++ b/man/man8/tipc-bearer.8
@@ -39,14 +39,12 @@ tipc-bearer \- show or modify TIPC bearers
 .B tipc bearer disable media
 .br
 .RB "{ { " eth " | " ib " } " device
-.IR DEVICE
+.IR "DEVICE " }
 .RB "|"
 .br
 .RB "{ " udp
 .B name
-.IR NAME
-.B localip
-.IR LOCALIP " } }"
+.IR NAME " }"
 .br
 
 .ti -8
@@ -65,9 +63,7 @@ tipc-bearer \- show or modify TIPC bearers
 .br
 .RB "{ " udp
 .B name
-.IR NAME
-.B localip
-.IR LOCALIP " } }"
+.IR NAME " }"
 .br
 
 .ti -8
@@ -80,9 +76,7 @@ tipc-bearer \- show or modify TIPC bearers
 .br
 .RB "{ " udp
 .B name
-.IR NAME
-.B localip
-.IR LOCALIP " } }"
+.IR NAME " }"
 .br
 
 .ti -8
-- 
2.1.4



[PATCH iproute2 2/2] tipc: refactor bearer identification

2016-08-09 Thread Richard Alpe
Introduce a generic function (nl_add_bearer_name()) that identifies a
bearer and adds it to an existing netlink message. This reduces code
complexity and makes the code a little bit easier to maintain.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 tipc/bearer.c | 312 --
 tipc/cmdl.h   |   6 ++
 2 files changed, 114 insertions(+), 204 deletions(-)

diff --git a/tipc/bearer.c b/tipc/bearer.c
index 30b54d9..018bc0d 100644
--- a/tipc/bearer.c
+++ b/tipc/bearer.c
@@ -29,7 +29,7 @@
 static void _print_bearer_opts(void)
 {
fprintf(stderr,
-   "\nOPTIONS\n"
+   "OPTIONS\n"
" priority  - Bearer link priority\n"
" tolerance - Bearer link tolerance\n"
" window- Bearer link window\n");
@@ -44,43 +44,27 @@ static void _print_bearer_media(void)
" eth   - Ethernet\n");
 }
 
-static void cmd_bearer_enable_l2_help(struct cmdl *cmdl)
+static void cmd_bearer_enable_l2_help(struct cmdl *cmdl, char *media)
 {
fprintf(stderr,
-   "Usage: %s bearer enable media MEDIA device DEVICE [OPTIONS]\n"
+   "Usage: %s bearer enable media %s device DEVICE [OPTIONS]\n"
"\nOPTIONS\n"
" domain DOMAIN - Discovery domain\n"
" priority PRIORITY - Bearer priority\n",
-   cmdl->argv[0]);
+   cmdl->argv[0], media);
 }
 
-static void cmd_bearer_enable_udp_help(struct cmdl *cmdl)
+static void cmd_bearer_enable_udp_help(struct cmdl *cmdl, char *media)
 {
fprintf(stderr,
-   "Usage: %s bearer enable media udp name NAME localip IP 
[OPTIONS]\n"
+   "Usage: %s bearer enable media %s name NAME localip IP 
[OPTIONS]\n"
"\nOPTIONS\n"
" domain DOMAIN - Discovery domain\n"
" priority PRIORITY - Bearer priority\n"
" localport PORT- Local UDP port (default 6118)\n"
" remoteip IP   - Remote IP address\n"
" remoteport IP - Remote UDP port (default 6118)\n",
-   cmdl->argv[0]);
-}
-
-static int enable_l2_bearer(struct nlmsghdr *nlh, struct opt *opts,
-   struct cmdl *cmdl)
-{
-   struct opt *opt;
-   char id[TIPC_MAX_BEARER_NAME];
-
-   if (!(opt = get_opt(opts, "device"))) {
-   fprintf(stderr, "error: missing bearer device\n");
-   return -EINVAL;
-   }
-   snprintf(id, sizeof(id), "eth:%s", opt->val);
-   mnl_attr_put_strz(nlh, TIPC_NLA_BEARER_NAME, id);
-
-   return 0;
+   cmdl->argv[0], media);
 }
 
 static int get_netid_cb(const struct nlmsghdr *nlh, void *data)
@@ -123,8 +107,8 @@ static int generate_multicast(short af, char *buf, int 
bufsize)
return 0;
 }
 
-static int enable_udp_bearer(struct nlmsghdr *nlh, struct opt *opts,
-struct cmdl *cmdl)
+static int nl_add_udp_enable_opts(struct nlmsghdr *nlh, struct opt *opts,
+ struct cmdl *cmdl)
 {
int err;
struct opt *opt;
@@ -134,7 +118,6 @@ static int enable_udp_bearer(struct nlmsghdr *nlh, struct 
opt *opts,
char *remport = "6118";
char *locip = NULL;
char *remip = NULL;
-   char name[TIPC_MAX_BEARER_NAME];
struct addrinfo *loc = NULL;
struct addrinfo *rem = NULL;
struct addrinfo hints = {
@@ -142,22 +125,9 @@ static int enable_udp_bearer(struct nlmsghdr *nlh, struct 
opt *opts,
.ai_socktype = SOCK_DGRAM
};
 
-   if (help_flag) {
-   cmd_bearer_enable_udp_help(cmdl);
-   /* TODO find a better error code? */
-   return -EINVAL;
-   }
-
-   if (!(opt = get_opt(opts, "name"))) {
-   fprintf(stderr, "error, udp bearer name missing\n");
-   cmd_bearer_enable_udp_help(cmdl);
-   return -EINVAL;
-   }
-   snprintf(name, sizeof(name), "udp:%s", opt->val);
-
if (!(opt = get_opt(opts, "localip"))) {
fprintf(stderr, "error, udp bearer localip missing\n");
-   cmd_bearer_enable_udp_help(cmdl);
+   cmd_bearer_enable_udp_help(cmdl, "udp");
return -EINVAL;
}
locip = opt->val;
@@ -197,8 +167,6 @@ static int enable_udp_bearer(struct nlmsghdr *nlh, struct 
opt *opts,
return -EINVAL;
}
 
-   mnl_attr_put_strz(nlh, TIPC_NLA_BEARER_NAME, name);
-
nest =

[PATCH net-next] tipc: fix nl compat regression for link statistics

2016-07-01 Thread Richard Alpe
Fix incorrect use of nla_strlcpy() where the first NLA_HDRLEN bytes
of the link name where left out.

Making the output of tipc-config -ls look something like:
Link statistics:
dcast-link
1:data0-1.1.2:data0
1:data0-1.1.3:data0

Also, for the record, the patch that introduce this regression
claims "Sending the whole object out can cause a leak". Which isn't
very likely as this is a compat layer, where the data we are parsing
is generated by us and we know the string to be NULL terminated. But
you can of course never be to secure.

Fixes: 5d2be1422e02 (tipc: fix an infoleak in tipc_nl_compat_link_dump)
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 net/tipc/netlink_compat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index 3ad9fab..1fd4647 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -604,7 +604,7 @@ static int tipc_nl_compat_link_dump(struct 
tipc_nl_compat_msg *msg,
 
link_info.dest = nla_get_flag(link[TIPC_NLA_LINK_DEST]);
link_info.up = htonl(nla_get_flag(link[TIPC_NLA_LINK_UP]));
-   nla_strlcpy(link_info.str, nla_data(link[TIPC_NLA_LINK_NAME]),
+   nla_strlcpy(link_info.str, link[TIPC_NLA_LINK_NAME],
TIPC_MAX_LINK_NAME);
 
return tipc_add_tlv(msg->rep, TIPC_TLV_LINK_INFO,
-- 
2.1.4



[PATCH net-next 2/2] tipc: rename udp_port in struct udp_media_addr

2016-06-27 Thread Richard Alpe
Context implies that port in struct "udp_media_addr" is referring
to a UDP port.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Ying Xue <ying@windriver.com>
---
 net/tipc/udp_media.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index c9cf2be..b016c01 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -63,7 +63,7 @@
  */
 struct udp_media_addr {
__be16  proto;
-   __be16  udp_port;
+   __be16  port;
union {
struct in_addr ipv4;
struct in6_addr ipv6;
@@ -108,9 +108,9 @@ static int tipc_udp_addr2str(struct tipc_media_addr *a, 
char *buf, int size)
struct udp_media_addr *ua = (struct udp_media_addr *)>value;
 
if (ntohs(ua->proto) == ETH_P_IP)
-   snprintf(buf, size, "%pI4:%u", >ipv4, ntohs(ua->udp_port));
+   snprintf(buf, size, "%pI4:%u", >ipv4, ntohs(ua->port));
else if (ntohs(ua->proto) == ETH_P_IPV6)
-   snprintf(buf, size, "%pI6:%u", >ipv6, ntohs(ua->udp_port));
+   snprintf(buf, size, "%pI6:%u", >ipv6, ntohs(ua->port));
else
pr_err("Invalid UDP media address\n");
return 0;
@@ -178,8 +178,8 @@ static int tipc_udp_send_msg(struct net *net, struct 
sk_buff *skb,
skb->dev = rt->dst.dev;
ttl = ip4_dst_hoplimit(>dst);
udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
-   dst->ipv4.s_addr, 0, ttl, 0, src->udp_port,
-   dst->udp_port, false, true);
+   dst->ipv4.s_addr, 0, ttl, 0, src->port,
+   dst->port, false, true);
 #if IS_ENABLED(CONFIG_IPV6)
} else {
struct dst_entry *ndst;
@@ -196,8 +196,8 @@ static int tipc_udp_send_msg(struct net *net, struct 
sk_buff *skb,
ttl = ip6_dst_hoplimit(ndst);
err = udp_tunnel6_xmit_skb(ndst, ub->ubsock->sk, skb,
   ndst->dev, >ipv6,
-  >ipv6, 0, ttl, 0, src->udp_port,
-  dst->udp_port, false);
+  >ipv6, 0, ttl, 0, src->port,
+  dst->port, false);
 #endif
}
return err;
@@ -292,12 +292,12 @@ err:
 
ip4 = (struct sockaddr_in *)_local;
local->proto = htons(ETH_P_IP);
-   local->udp_port = ip4->sin_port;
+   local->port = ip4->sin_port;
local->ipv4.s_addr = ip4->sin_addr.s_addr;
 
ip4 = (struct sockaddr_in *)_remote;
remote->proto = htons(ETH_P_IP);
-   remote->udp_port = ip4->sin_port;
+   remote->port = ip4->sin_port;
remote->ipv4.s_addr = ip4->sin_addr.s_addr;
return 0;
 
@@ -312,13 +312,13 @@ err:
return -EINVAL;
 
local->proto = htons(ETH_P_IPV6);
-   local->udp_port = ip6->sin6_port;
+   local->port = ip6->sin6_port;
memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
ub->ifindex = ip6->sin6_scope_id;
 
ip6 = (struct sockaddr_in6 *)_remote;
remote->proto = htons(ETH_P_IPV6);
-   remote->udp_port = ip6->sin6_port;
+   remote->port = ip6->sin6_port;
memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
return 0;
 #endif
@@ -386,7 +386,7 @@ static int tipc_udp_enable(struct net *net, struct 
tipc_bearer *b,
err = -EAFNOSUPPORT;
goto err;
}
-   udp_conf.local_udp_port = local.udp_port;
+   udp_conf.local_udp_port = local.port;
err = udp_sock_create(net, _conf, >ubsock);
if (err)
goto err;
-- 
2.1.4



[PATCH net-next 1/2] tipc: honor msg2addr return value

2016-06-27 Thread Richard Alpe
The UDP msg2addr function tipc_udp_msg2addr() can return -EINVAL which
prior to this patch was unhanded in the caller.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Ying Xue <ying@windriver.com>
---
 net/tipc/discover.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index ad9d477..6b109a8 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -135,9 +135,12 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
u16 caps = msg_node_capabilities(hdr);
bool respond = false;
bool dupl_addr = false;
+   int err;
 
-   bearer->media->msg2addr(bearer, , msg_media_addr(hdr));
+   err = bearer->media->msg2addr(bearer, , msg_media_addr(hdr));
kfree_skb(skb);
+   if (err)
+   return;
 
/* Ensure message from node is valid and communication is permitted */
if (net_id != tn->net_id)
-- 
2.1.4



[PATCH net] tipc: fix nametable publication field in nl compat

2016-05-17 Thread Richard Alpe
The publication field of the old netlink API should contain the
publication key and not the publication reference.

Fixes: 44a8ae94fd55 (tipc: convert legacy nl name table dump to nl compat)
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
---
 net/tipc/netlink_compat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index d7d050f..4dfc5c1 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -802,7 +802,7 @@ static int tipc_nl_compat_name_table_dump(struct 
tipc_nl_compat_msg *msg,
goto out;
 
tipc_tlv_sprintf(msg->rep, "%-10u %s",
-nla_get_u32(publ[TIPC_NLA_PUBL_REF]),
+nla_get_u32(publ[TIPC_NLA_PUBL_KEY]),
 scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);
 out:
tipc_tlv_sprintf(msg->rep, "\n");
-- 
2.1.4



[PATCH net-next] tipc: check nl sock before parsing nested attributes

2016-05-16 Thread Richard Alpe
Make sure the socket for which the user is listing publication exists
before parsing the socket netlink attributes.

Prior to this patch a call without any socket caused a NULL pointer
dereference in tipc_nl_publ_dump().

Tested-and-reported-by: Baozeng Ding <splovi...@gmail.com>
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 net/tipc/socket.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 1262889..3b7a799 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2853,6 +2853,9 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct 
netlink_callback *cb)
if (err)
return err;
 
+   if (!attrs[TIPC_NLA_SOCK])
+   return -EINVAL;
+
err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX,
   attrs[TIPC_NLA_SOCK],
   tipc_nl_sock_policy);
-- 
2.1.4



[PATCH net-next v1] tipc: make sure IPv6 header fits in skb headroom

2016-03-14 Thread Richard Alpe
Expand headroom further in order to be able to fit the larger IPv6
header. Prior to this patch this caused a skb under panic for certain
tipc packets when using IPv6 UDP bearer(s).

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
---
 net/tipc/udp_media.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 49b3c2e..6364cff 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -53,7 +53,7 @@
 /* IANA assigned UDP port */
 #define UDP_PORT_DEFAULT   6118
 
-#define UDP_MIN_HEADROOM28
+#define UDP_MIN_HEADROOM48
 
 /**
  * struct udp_media_addr - IP/UDP addressing information
-- 
2.1.4



[PATCH net-next v2] tipc: move netlink policies to netlink.c

2016-03-04 Thread Richard Alpe
Make the c files less cluttered and enable netlink attributes to be
shared between files.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvara...@ericsson.com>
---
 net/tipc/bearer.c | 18 +-
 net/tipc/link.c   |  8 --
 net/tipc/name_table.c |  6 -
 net/tipc/net.c|  6 +
 net/tipc/netlink.c| 69 +++
 net/tipc/netlink.h| 11 
 net/tipc/node.c   | 23 +
 net/tipc/socket.c |  9 +--
 net/tipc/udp_media.c  |  9 +--
 9 files changed, 85 insertions(+), 74 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 802ffad..27a5406 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -40,6 +40,7 @@
 #include "link.h"
 #include "discover.h"
 #include "bcast.h"
+#include "netlink.h"
 
 #define MAX_ADDR_STR 60
 
@@ -54,23 +55,6 @@ static struct tipc_media * const media_info_array[] = {
NULL
 };
 
-static const struct nla_policy
-tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = {
-   [TIPC_NLA_BEARER_UNSPEC]= { .type = NLA_UNSPEC },
-   [TIPC_NLA_BEARER_NAME] = {
-   .type = NLA_STRING,
-   .len = TIPC_MAX_BEARER_NAME
-   },
-   [TIPC_NLA_BEARER_PROP]  = { .type = NLA_NESTED },
-   [TIPC_NLA_BEARER_DOMAIN]= { .type = NLA_U32 }
-};
-
-static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {
-   [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC },
-   [TIPC_NLA_MEDIA_NAME]   = { .type = NLA_STRING },
-   [TIPC_NLA_MEDIA_PROP]   = { .type = NLA_NESTED }
-};
-
 static void bearer_disable(struct net *net, struct tipc_bearer *b);
 
 /**
diff --git a/net/tipc/link.c b/net/tipc/link.c
index e31d92f..c46d620 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -195,14 +195,6 @@ struct tipc_link {
 static const char *link_co_err = "Link tunneling error, ";
 static const char *link_rst_msg = "Resetting link ";
 
-/* Properties valid for media, bearar and link */
-static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
-   [TIPC_NLA_PROP_UNSPEC]  = { .type = NLA_UNSPEC },
-   [TIPC_NLA_PROP_PRIO]= { .type = NLA_U32 },
-   [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 },
-   [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }
-};
-
 /* Send states for broadcast NACKs
  */
 enum {
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 777b979..e190460 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -47,12 +47,6 @@
 
 #define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
 
-static const struct nla_policy
-tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = {
-   [TIPC_NLA_NAME_TABLE_UNSPEC]= { .type = NLA_UNSPEC },
-   [TIPC_NLA_NAME_TABLE_PUBL]  = { .type = NLA_NESTED }
-};
-
 /**
  * struct name_info - name sequence publication info
  * @node_list: circular list of publications made by own node
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 77bf911..d7a5c11 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -41,11 +41,7 @@
 #include "socket.h"
 #include "node.h"
 #include "bcast.h"
-
-static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
-   [TIPC_NLA_NET_UNSPEC]   = { .type = NLA_UNSPEC },
-   [TIPC_NLA_NET_ID]   = { .type = NLA_U32 }
-};
+#include "netlink.h"
 
 /*
  * The TIPC locking policy is designed to ensure a very fine locking
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 8975b01..56935df2 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -55,6 +55,75 @@ static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 
1] = {
[TIPC_NLA_NAME_TABLE]   = { .type = NLA_NESTED, }
 };
 
+const struct nla_policy
+tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = {
+   [TIPC_NLA_NAME_TABLE_UNSPEC]= { .type = NLA_UNSPEC },
+   [TIPC_NLA_NAME_TABLE_PUBL]  = { .type = NLA_NESTED }
+};
+
+const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = {
+   [TIPC_NLA_SOCK_UNSPEC]  = { .type = NLA_UNSPEC },
+   [TIPC_NLA_SOCK_ADDR]= { .type = NLA_U32 },
+   [TIPC_NLA_SOCK_REF] = { .type = NLA_U32 },
+   [TIPC_NLA_SOCK_CON] = { .type = NLA_NESTED },
+   [TIPC_NLA_SOCK_HAS_PUBL]= { .type = NLA_FLAG }
+};
+
+const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
+   [TIPC_NLA_NET_UNSPEC]   = { .type = NLA_UNSPEC },
+   [TIPC_NLA_NET_ID]   = { .type = NLA_U32 }
+};
+
+const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
+   [T

[PATCH net-next v1 3/4] tipc: safely copy UDP netlink data from user

2016-03-03 Thread Richard Alpe
The netlink policy for TIPC_NLA_UDP_LOCAL and TIPC_NLA_UDP_REMOTE
is of type binary with a defined length. This causes the policy
framework to threat the defined length as maximum length.

There is however no protection against a user sending a smaller
amount of data. Prior to this patch this wasn't handled which could
result in a partially incomplete sockaddr_storage struct containing
uninitialized data.

In this patch we use nla_memcpy() when copying the user data. This
ensures a potential gap at the end is cleared out properly.

This was found by Julia with Coccinelle tool.

Reported-by: Daniel Borkmann <dan...@iogearbox.net>
Reported-by: Julia Lawall <julia.law...@lip6.fr>
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
Reviewed-by: Erik Hugne <erik.hu...@gmail.com>
---
 net/tipc/udp_media.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index f22a5bb1..6fe8740 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -276,7 +276,7 @@ static int parse_options(struct nlattr *attrs[], struct 
udp_bearer *ub,
 struct udp_media_addr *remote)
 {
struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
-   struct sockaddr_storage *sa_local, *sa_remote;
+   struct sockaddr_storage sa_local, sa_remote;
 
if (!attrs[TIPC_NLA_BEARER_UDP_OPTS])
goto err;
@@ -285,41 +285,43 @@ static int parse_options(struct nlattr *attrs[], struct 
udp_bearer *ub,
 tipc_nl_udp_policy))
goto err;
if (opts[TIPC_NLA_UDP_LOCAL] && opts[TIPC_NLA_UDP_REMOTE]) {
-   sa_local = nla_data(opts[TIPC_NLA_UDP_LOCAL]);
-   sa_remote = nla_data(opts[TIPC_NLA_UDP_REMOTE]);
+   nla_memcpy(_local, opts[TIPC_NLA_UDP_LOCAL],
+  sizeof(sa_local));
+   nla_memcpy(_remote, opts[TIPC_NLA_UDP_REMOTE],
+  sizeof(sa_remote));
} else {
 err:
pr_err("Invalid UDP bearer configuration");
return -EINVAL;
}
-   if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET) {
+   if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET) {
struct sockaddr_in *ip4;
 
-   ip4 = (struct sockaddr_in *)sa_local;
+   ip4 = (struct sockaddr_in *)_local;
local->proto = htons(ETH_P_IP);
local->udp_port = ip4->sin_port;
local->ipv4.s_addr = ip4->sin_addr.s_addr;
 
-   ip4 = (struct sockaddr_in *)sa_remote;
+   ip4 = (struct sockaddr_in *)_remote;
remote->proto = htons(ETH_P_IP);
remote->udp_port = ip4->sin_port;
remote->ipv4.s_addr = ip4->sin_addr.s_addr;
return 0;
 
 #if IS_ENABLED(CONFIG_IPV6)
-   } else if ((sa_local->ss_family & sa_remote->ss_family) == AF_INET6) {
+   } else if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET6) {
struct sockaddr_in6 *ip6;
 
-   ip6 = (struct sockaddr_in6 *)sa_local;
+   ip6 = (struct sockaddr_in6 *)_local;
local->proto = htons(ETH_P_IPV6);
local->udp_port = ip6->sin6_port;
-   local->ipv6 = ip6->sin6_addr;
+   memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
ub->ifindex = ip6->sin6_scope_id;
 
-   ip6 = (struct sockaddr_in6 *)sa_remote;
+   ip6 = (struct sockaddr_in6 *)_remote;
remote->proto = htons(ETH_P_IPV6);
remote->udp_port = ip6->sin6_port;
-   remote->ipv6 = ip6->sin6_addr;
+   memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
return 0;
 #endif
}
-- 
2.1.4



[PATCH net-next v1 4/4] tipc: make sure required IPv6 addresses are scoped

2016-03-03 Thread Richard Alpe
Make sure the user has provided a scope for multicast and link local
addresses used locally by a UDP bearer.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
Reviewed-by: Erik Hugne <erik.hu...@gmail.com>
---
 net/tipc/udp_media.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index 6fe8740..fb2f7ec6 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -310,9 +310,14 @@ err:
 
 #if IS_ENABLED(CONFIG_IPV6)
} else if ((sa_local.ss_family & sa_remote.ss_family) == AF_INET6) {
+   int atype;
struct sockaddr_in6 *ip6;
 
ip6 = (struct sockaddr_in6 *)_local;
+   atype = ipv6_addr_type(>sin6_addr);
+   if (__ipv6_addr_needs_scope_id(atype) && !ip6->sin6_scope_id)
+   return -EINVAL;
+
local->proto = htons(ETH_P_IPV6);
local->udp_port = ip6->sin6_port;
memcpy(>ipv6, >sin6_addr, sizeof(struct in6_addr));
-- 
2.1.4



[PATCH net-next v1 2/4] tipc: don't check link reset on non existing link

2016-03-03 Thread Richard Alpe
Make sure we have a link before checking if it has been reset or not.

Prior to this patch tipc_link_is_reset() could be called with a non
existing link, resulting in a null pointer dereference.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
Reviewed-by: Erik Hugne <erik.hu...@gmail.com>
---
 net/tipc/node.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/tipc/node.c b/net/tipc/node.c
index cdb7950..590d597 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -843,7 +843,7 @@ void tipc_node_check_dest(struct net *net, u32 onode,
memcpy(>maddr, maddr, sizeof(*maddr));
 exit:
tipc_node_write_unlock(n);
-   if (reset && !tipc_link_is_reset(l))
+   if (reset && l && !tipc_link_is_reset(l))
tipc_node_link_down(n, b->identity, false);
tipc_node_put(n);
 }
-- 
2.1.4



[PATCH net-next v1 1/4] tipc: add net device to skb before UDP xmit

2016-03-03 Thread Richard Alpe
Prior to this patch enabling a IPv4 UDP bearer caused a null pointer
dereference in iptunnel_xmit_stats(), when it tried to dereference the
net device from the skb. To resolve this we now point the skb device
to the net device resolved from the routing table.

Fixes: 039f50629b7f (ip_tunnel: Move stats update to iptunnel_xmit())
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
Reviewed-by: Erik Hugne <erik.hu...@gmail.com>
---
 net/tipc/udp_media.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index d63a911..f22a5bb1 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -181,6 +181,8 @@ static int tipc_udp_send_msg(struct net *net, struct 
sk_buff *skb,
err = PTR_ERR(rt);
goto tx_error;
}
+
+   skb->dev = rt->dst.dev;
ttl = ip4_dst_hoplimit(>dst);
udp_tunnel_xmit_skb(rt, ub->ubsock->sk, skb, src->ipv4.s_addr,
dst->ipv4.s_addr, 0, ttl, 0, src->udp_port,
-- 
2.1.4



[PATCH net-next v1] tipc: refactor node xmit and fix memory leaks

2016-02-11 Thread Richard Alpe
Refactor tipc_node_xmit() to fail fast and fail early. Fix several
potential memory leaks in unexpected error paths.

Reported-by: Dmitry Vyukov <dvyu...@google.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 net/tipc/link.c |  8 ++--
 net/tipc/node.c | 54 --
 2 files changed, 38 insertions(+), 24 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 6f4a6d9..3e513da 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -903,8 +903,10 @@ int tipc_link_xmit(struct tipc_link *l, struct 
sk_buff_head *list,
if (unlikely(l->backlog[i].len >= l->backlog[i].limit))
return link_schedule_user(l, list);
}
-   if (unlikely(msg_size(hdr) > mtu))
+   if (unlikely(msg_size(hdr) > mtu)) {
+   skb_queue_purge(list);
return -EMSGSIZE;
+   }
 
/* Prepare each packet for sending, and add to relevant queue: */
while (skb_queue_len(list)) {
@@ -916,8 +918,10 @@ int tipc_link_xmit(struct tipc_link *l, struct 
sk_buff_head *list,
 
if (likely(skb_queue_len(transmq) < maxwin)) {
_skb = skb_clone(skb, GFP_ATOMIC);
-   if (!_skb)
+   if (!_skb) {
+   skb_queue_purge(list);
return -ENOBUFS;
+   }
__skb_dequeue(list);
__skb_queue_tail(transmq, skb);
__skb_queue_tail(xmitq, _skb);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index f8a8255..10a1e87 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1166,7 +1166,7 @@ msg_full:
  * @dnode: address of destination node
  * @selector: a number used for deterministic link selection
  * Consumes the buffer chain, except when returning -ELINKCONG
- * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
+ * Returns 0 if success, otherwise: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE,-ENOBUF
  */
 int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
   u32 dnode, int selector)
@@ -1174,33 +1174,43 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head 
*list,
struct tipc_link_entry *le = NULL;
struct tipc_node *n;
struct sk_buff_head xmitq;
-   int bearer_id = -1;
-   int rc = -EHOSTUNREACH;
+   int bearer_id;
+   int rc;
+
+   if (in_own_node(net, dnode)) {
+   tipc_sk_rcv(net, list);
+   return 0;
+   }
 
-   __skb_queue_head_init();
n = tipc_node_find(net, dnode);
-   if (likely(n)) {
-   tipc_node_read_lock(n);
-   bearer_id = n->active_links[selector & 1];
-   if (bearer_id >= 0) {
-   le = >links[bearer_id];
-   spin_lock_bh(>lock);
-   rc = tipc_link_xmit(le->link, list, );
-   spin_unlock_bh(>lock);
-   }
+   if (unlikely(!n)) {
+   skb_queue_purge(list);
+   return -EHOSTUNREACH;
+   }
+
+   tipc_node_read_lock(n);
+   bearer_id = n->active_links[selector & 1];
+   if (unlikely(bearer_id == INVALID_BEARER_ID)) {
tipc_node_read_unlock(n);
-   if (likely(!rc))
-   tipc_bearer_xmit(net, bearer_id, , >maddr);
-   else if (rc == -ENOBUFS)
-   tipc_node_link_down(n, bearer_id, false);
tipc_node_put(n);
-   return rc;
+   skb_queue_purge(list);
+   return -EHOSTUNREACH;
}
 
-   if (likely(in_own_node(net, dnode))) {
-   tipc_sk_rcv(net, list);
-   return 0;
-   }
+   __skb_queue_head_init();
+   le = >links[bearer_id];
+   spin_lock_bh(>lock);
+   rc = tipc_link_xmit(le->link, list, );
+   spin_unlock_bh(>lock);
+   tipc_node_read_unlock(n);
+
+   if (likely(rc == 0))
+   tipc_bearer_xmit(net, bearer_id, , >maddr);
+   else if (rc == -ENOBUFS)
+   tipc_node_link_down(n, bearer_id, false);
+
+   tipc_node_put(n);
+
return rc;
 }
 
-- 
2.1.4



[PATCH net-next v1 1/2] tipc: fix link attribute propagation bug

2016-01-31 Thread Richard Alpe
Changing certain link attributes (link tolerance and link priority)
from the TIPC management tool is supposed to automatically take
effect at both endpoints of the affected link.

Currently the media address is not instantiated for the link and is
used uninstantiated when crafting protocol messages designated for the
peer endpoint. This means that changing a link property currently
results in the property being changed on the local machine but the
protocol message designated for the peer gets lost. Resulting in
property discrepancy between the endpoints.

In this patch we resolve this by using the media address from the
link entry and using the bearer transmit function to send it. Hence,
we can now eliminate the redundant function tipc_link_prot_xmit() and
the redundant field tipc_link::media_addr.

Fixes: 2af5ae372a4b (tipc: clean up unused code and structures)
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Reported-by: Jason Hu <huzhiji...@gmail.com>
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 net/tipc/link.c | 31 ++-
 net/tipc/link.h |  6 --
 net/tipc/node.c |  9 ++---
 3 files changed, 16 insertions(+), 30 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0c2944f..f156353 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -123,7 +123,6 @@ struct tipc_stats {
 struct tipc_link {
u32 addr;
char name[TIPC_MAX_LINK_NAME];
-   struct tipc_media_addr *media_addr;
struct net *net;
 
/* Management and link supervision data */
@@ -1261,26 +1260,6 @@ drop:
return rc;
 }
 
-/*
- * Send protocol message to the other endpoint.
- */
-static void tipc_link_proto_xmit(struct tipc_link *l, u32 msg_typ,
-int probe_msg, u32 gap, u32 tolerance,
-u32 priority)
-{
-   struct sk_buff *skb = NULL;
-   struct sk_buff_head xmitq;
-
-   __skb_queue_head_init();
-   tipc_link_build_proto_msg(l, msg_typ, probe_msg, gap,
- tolerance, priority, );
-   skb = __skb_dequeue();
-   if (!skb)
-   return;
-   tipc_bearer_xmit_skb(l->net, l->bearer_id, skb, l->media_addr);
-   l->rcv_unacked = 0;
-}
-
 static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool 
probe,
  u16 rcvgap, int tolerance, int priority,
  struct sk_buff_head *xmitq)
@@ -2021,16 +2000,18 @@ msg_full:
return -EMSGSIZE;
 }
 
-void tipc_link_set_tolerance(struct tipc_link *l, u32 tol)
+void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
+struct sk_buff_head *xmitq)
 {
l->tolerance = tol;
-   tipc_link_proto_xmit(l, STATE_MSG, 0, 0, tol, 0);
+   tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, tol, 0, xmitq);
 }
 
-void tipc_link_set_prio(struct tipc_link *l, u32 prio)
+void tipc_link_set_prio(struct tipc_link *l, u32 prio,
+   struct sk_buff_head *xmitq)
 {
l->priority = prio;
-   tipc_link_proto_xmit(l, STATE_MSG, 0, 0, 0, prio);
+   tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, prio, xmitq);
 }
 
 void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit)
diff --git a/net/tipc/link.h b/net/tipc/link.h
index b2ae0f4..b4ee9d6 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -112,8 +112,10 @@ char tipc_link_plane(struct tipc_link *l);
 int tipc_link_prio(struct tipc_link *l);
 int tipc_link_window(struct tipc_link *l);
 unsigned long tipc_link_tolerance(struct tipc_link *l);
-void tipc_link_set_tolerance(struct tipc_link *l, u32 tol);
-void tipc_link_set_prio(struct tipc_link *l, u32 prio);
+void tipc_link_set_tolerance(struct tipc_link *l, u32 tol,
+struct sk_buff_head *xmitq);
+void tipc_link_set_prio(struct tipc_link *l, u32 prio,
+   struct sk_buff_head *xmitq);
 void tipc_link_set_abort_limit(struct tipc_link *l, u32 limit);
 void tipc_link_set_queue_limits(struct tipc_link *l, u32 window);
 int __tipc_nl_add_link(struct net *net, struct tipc_nl_msg *msg,
diff --git a/net/tipc/node.c b/net/tipc/node.c
index fa97d96..f8a8255 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1637,9 +1637,12 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct 
genl_info *info)
char *name;
struct tipc_link *link;
struct tipc_node *node;
+   struct sk_buff_head xmitq;
struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1];
struct net *net = sock_net(skb->sk);
 
+   __skb_queue_head_init();
+
if (!info->attrs[TIPC_NLA_LINK])
return -EINVAL;
 
@@ -1683,13 +1686,13 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct 
genl_info *info)
u32 tol;
 
tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
-  

[PATCH net-next v1 2/2] tipc: fix link priority propagation

2016-01-31 Thread Richard Alpe
Currently link priority changes isn't handled for active links. In
this patch we resolve this by changing our priority if the peer passes
a valid priority in a state message.

Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
---
 net/tipc/link.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index f156353..6f4a6d9 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1458,6 +1458,12 @@ static int tipc_link_proto_rcv(struct tipc_link *l, 
struct sk_buff *skb,
if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL))
l->tolerance = peers_tol;
 
+   if (peers_prio && in_range(peers_prio, TIPC_MIN_LINK_PRI,
+  TIPC_MAX_LINK_PRI)) {
+   l->priority = peers_prio;
+   rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT);
+   }
+
l->silent_intv_cnt = 0;
l->stats.recv_states++;
if (msg_probe(hdr))
-- 
2.1.4



Re: [PATCH net-next v1 1/2] tipc: move netlink policies to netlink.h

2016-01-07 Thread Richard Alpe
On 2016-01-05 22:47, David Miller wrote:
> From: Richard Alpe <richard.a...@ericsson.com>
> Date: Tue, 5 Jan 2016 10:56:16 +0100
> 
>> Make the c files less cluttered and enable netlink attributes to be
>> shared between files. This will prove useful in a future patch where a
>> node message will contain a nested network.
>>
>> Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
>> Acked-by: Jon Maloy <jon.ma...@ericsson.com>
> 
> netlink.h is included by more than one file, which means the tables
> (might) be instantiated multiple times.
I thought about that, but I assumed unreferenced tables would be
optimized away by the compiler (?)
> 
> I'd really recommend not putting such tables in a header file that
> is used in this way.
Alright, I will drop the patch.

Do you have any suggestion on how to handle the case where a policy
(table) is shared between c files, like the net policy in the
subsequent patch? I could perhaps use extern in the c files (which
seems frown upon) or duplicate the policy? :-S

Thanks for the review
Richard
> 
> Thanks.
> 

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH iproute2 2/2] tipc: add peer remove functionality

2016-01-05 Thread Richard Alpe
This enables a user to remove an offline peer from the kernel data
structures. This could for example be useful when deliberately scaling
in peer nodes in a cloud environment.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Reviewed-by: Ying Xue <ying@windriver.com>
---
 include/linux/tipc_netlink.h |  1 +
 man/man8/tipc-bearer.8   |  1 +
 man/man8/tipc-link.8 |  1 +
 man/man8/tipc-media.8|  1 +
 man/man8/tipc-nametable.8|  1 +
 man/man8/tipc-node.8 |  1 +
 man/man8/tipc-peer.8 | 52 +
 man/man8/tipc.8  |  1 +
 tipc/Makefile|  2 +-
 tipc/peer.c  | 93 
 tipc/peer.h  | 21 ++
 tipc/tipc.c  |  3 ++
 12 files changed, 177 insertions(+), 1 deletion(-)
 create mode 100644 man/man8/tipc-peer.8
 create mode 100644 tipc/peer.c
 create mode 100644 tipc/peer.h

diff --git a/include/linux/tipc_netlink.h b/include/linux/tipc_netlink.h
index d4c8f14..25eb645 100644
--- a/include/linux/tipc_netlink.h
+++ b/include/linux/tipc_netlink.h
@@ -56,6 +56,7 @@ enum {
TIPC_NL_NET_GET,
TIPC_NL_NET_SET,
TIPC_NL_NAME_TABLE_GET,
+   TIPC_NL_PEER_REMOVE,
 
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/man/man8/tipc-bearer.8 b/man/man8/tipc-bearer.8
index 50a1ed2..565ee01 100644
--- a/man/man8/tipc-bearer.8
+++ b/man/man8/tipc-bearer.8
@@ -218,6 +218,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-media (8),
 .BR tipc-nametable (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-link.8 b/man/man8/tipc-link.8
index 3be8c9a..2ee03a0 100644
--- a/man/man8/tipc-link.8
+++ b/man/man8/tipc-link.8
@@ -213,6 +213,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-bearer (8),
 .BR tipc-nametable (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-media.8 b/man/man8/tipc-media.8
index 6c6e2b1..4689cb3 100644
--- a/man/man8/tipc-media.8
+++ b/man/man8/tipc-media.8
@@ -74,6 +74,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-link (8),
 .BR tipc-nametable (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-nametable.8 b/man/man8/tipc-nametable.8
index d3397f9..4bcefe4 100644
--- a/man/man8/tipc-nametable.8
+++ b/man/man8/tipc-nametable.8
@@ -87,6 +87,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-link (8),
 .BR tipc-media (8),
 .BR tipc-node (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-node.8 b/man/man8/tipc-node.8
index ef32ec7..a72a409 100644
--- a/man/man8/tipc-node.8
+++ b/man/man8/tipc-node.8
@@ -59,6 +59,7 @@ Exit status is 0 if command was successful or a positive 
integer upon failure.
 .BR tipc-link (8),
 .BR tipc-media (8),
 .BR tipc-nametable (8),
+.BR tipc-peer (8),
 .BR tipc-socket (8)
 .br
 .SH REPORTING BUGS
diff --git a/man/man8/tipc-peer.8 b/man/man8/tipc-peer.8
new file mode 100644
index 000..430651f
--- /dev/null
+++ b/man/man8/tipc-peer.8
@@ -0,0 +1,52 @@
+.TH TIPC-PEER 8 "04 Dec 2015" "iproute2" "Linux"
+
+.\" For consistency, please keep padding right aligned.
+.\" For example '.B "foo " bar' and not '.B foo " bar"'
+
+.SH NAME
+tipc-peer \- modify peer information
+
+.SH SYNOPSIS
+.ad l
+.in +8
+
+.ti -8
+.B tipc peer remove address
+.IR ADDRESS
+
+.SH OPTIONS
+Options (flags) that can be passed anywhere in the command chain.
+.TP
+.BR "\-h" , " --help"
+Show help about last valid command. For example
+.B tipc peer --help
+will show peer help and
+.B tipc --help
+will show general help. The position of the option in the string is irrelevant.
+.SH DESCRIPTION
+
+.SS Peer remove
+Remove an offline peer node from the local data structures. The peer is
+identified by its
+.B address
+
+.SH EXIT STATUS
+Exit status is 0 if command was successful or a positive integer upon failure.
+
+.SH SEE ALSO
+.BR tipc (8),
+.BR tipc-bearer (8),
+.BR tipc-link (8),
+.BR tipc-media (8),
+.BR tipc-nametable (8),
+.BR tipc-node (8),
+.BR tipc-socket (8)
+.br
+.SH REPORTING BUGS
+Report any bugs to the Network Developers mailing list
+.B <netdev@vger.kernel.org>
+where the development and maintenance is primarily done.
+You do not have to be subscribed to the list to send a message there.
+
+.SH AUTHOR
+Richard Alpe <richard.a...@ericsson.com>
diff --git a/man/man8/tipc.8 b/man/man8/tipc.8
index c116552..32943fa 100644
--- a/man/man8/tipc.8
+++ b/man/man8/tipc.8
@@ -87,6 +87,7 @@ Exit statu

[PATCH net-next v1 1/2] tipc: move netlink policies to netlink.h

2016-01-05 Thread Richard Alpe
Make the c files less cluttered and enable netlink attributes to be
shared between files. This will prove useful in a future patch where a
node message will contain a nested network.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Acked-by: Jon Maloy <jon.ma...@ericsson.com>
---
 net/tipc/bearer.c | 19 +---
 net/tipc/link.c   |  8 -
 net/tipc/name_table.c |  7 +
 net/tipc/net.c|  6 +---
 net/tipc/netlink.c| 13 +---
 net/tipc/netlink.h| 85 +++
 net/tipc/node.c   | 23 +-
 net/tipc/socket.c |  9 +-
 net/tipc/udp_media.c  |  9 +-
 9 files changed, 92 insertions(+), 87 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 802ffad..d654cfe 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -40,6 +40,7 @@
 #include "link.h"
 #include "discover.h"
 #include "bcast.h"
+#include "netlink.h"
 
 #define MAX_ADDR_STR 60
 
@@ -53,24 +54,6 @@ static struct tipc_media * const media_info_array[] = {
 #endif
NULL
 };
-
-static const struct nla_policy
-tipc_nl_bearer_policy[TIPC_NLA_BEARER_MAX + 1] = {
-   [TIPC_NLA_BEARER_UNSPEC]= { .type = NLA_UNSPEC },
-   [TIPC_NLA_BEARER_NAME] = {
-   .type = NLA_STRING,
-   .len = TIPC_MAX_BEARER_NAME
-   },
-   [TIPC_NLA_BEARER_PROP]  = { .type = NLA_NESTED },
-   [TIPC_NLA_BEARER_DOMAIN]= { .type = NLA_U32 }
-};
-
-static const struct nla_policy tipc_nl_media_policy[TIPC_NLA_MEDIA_MAX + 1] = {
-   [TIPC_NLA_MEDIA_UNSPEC] = { .type = NLA_UNSPEC },
-   [TIPC_NLA_MEDIA_NAME]   = { .type = NLA_STRING },
-   [TIPC_NLA_MEDIA_PROP]   = { .type = NLA_NESTED }
-};
-
 static void bearer_disable(struct net *net, struct tipc_bearer *b);
 
 /**
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0c2944f..cb807be 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -196,14 +196,6 @@ struct tipc_link {
 static const char *link_co_err = "Link tunneling error, ";
 static const char *link_rst_msg = "Resetting link ";
 
-/* Properties valid for media, bearar and link */
-static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
-   [TIPC_NLA_PROP_UNSPEC]  = { .type = NLA_UNSPEC },
-   [TIPC_NLA_PROP_PRIO]= { .type = NLA_U32 },
-   [TIPC_NLA_PROP_TOL] = { .type = NLA_U32 },
-   [TIPC_NLA_PROP_WIN] = { .type = NLA_U32 }
-};
-
 /* Send states for broadcast NACKs
  */
 enum {
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 91fce70..75992b5 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -44,15 +44,10 @@
 #include "addr.h"
 #include "node.h"
 #include 
+#include "netlink.h"
 
 #define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
 
-static const struct nla_policy
-tipc_nl_name_table_policy[TIPC_NLA_NAME_TABLE_MAX + 1] = {
-   [TIPC_NLA_NAME_TABLE_UNSPEC]= { .type = NLA_UNSPEC },
-   [TIPC_NLA_NAME_TABLE_PUBL]  = { .type = NLA_NESTED }
-};
-
 /**
  * struct name_info - name sequence publication info
  * @node_list: circular list of publications made by own node
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 77bf911..d7a5c11 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -41,11 +41,7 @@
 #include "socket.h"
 #include "node.h"
 #include "bcast.h"
-
-static const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
-   [TIPC_NLA_NET_UNSPEC]   = { .type = NLA_UNSPEC },
-   [TIPC_NLA_NET_ID]   = { .type = NLA_U32 }
-};
+#include "netlink.h"
 
 /*
  * The TIPC locking policy is designed to ensure a very fine locking
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 8975b01..234cb93 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -42,18 +42,7 @@
 #include "node.h"
 #include "net.h"
 #include 
-
-static const struct nla_policy tipc_nl_policy[TIPC_NLA_MAX + 1] = {
-   [TIPC_NLA_UNSPEC]   = { .type = NLA_UNSPEC, },
-   [TIPC_NLA_BEARER]   = { .type = NLA_NESTED, },
-   [TIPC_NLA_SOCK] = { .type = NLA_NESTED, },
-   [TIPC_NLA_PUBL] = { .type = NLA_NESTED, },
-   [TIPC_NLA_LINK] = { .type = NLA_NESTED, },
-   [TIPC_NLA_MEDIA]= { .type = NLA_NESTED, },
-   [TIPC_NLA_NODE] = { .type = NLA_NESTED, },
-   [TIPC_NLA_NET]  = { .type = NLA_NESTED, },
-   [TIPC_NLA_NAME_TABLE]   = { .type = NLA_NESTED, }
-};
+#include "netlink.h"
 
 /* Users of the legacy API (tipc-config) can't handle that we add operations,
  * so we have a separate genl handling for the new API.
diff --git a/net/tipc/netlink.h b/net/tipc/netlink.h
index 08a1db6..ff7a39da 100644
--- a/net/tipc/netlink.h
+++ b/net/tipc/

[PATCH net-next v1 2/2] tipc: add peer removal functionality

2016-01-05 Thread Richard Alpe
Add TIPC_NL_PEER_REMOVE netlink command. This command can remove
an offline peer node from the internal data structures.

This will be supported by the tipc user space tool in iproute2.

Signed-off-by: Richard Alpe <richard.a...@ericsson.com>
Reviewed-by: Jon Maloy <jon.ma...@ericsson.com>
Acked-by: Ying Xue <ying@windriver.com>
---
 include/uapi/linux/tipc_netlink.h |  1 +
 net/tipc/net.c|  2 +-
 net/tipc/netlink.c|  5 
 net/tipc/node.c   | 60 +++
 net/tipc/node.h   |  3 +-
 5 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/include/uapi/linux/tipc_netlink.h 
b/include/uapi/linux/tipc_netlink.h
index d4c8f14..25eb645 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -56,6 +56,7 @@ enum {
TIPC_NL_NET_GET,
TIPC_NL_NET_SET,
TIPC_NL_NAME_TABLE_GET,
+   TIPC_NL_PEER_REMOVE,
 
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
diff --git a/net/tipc/net.c b/net/tipc/net.c
index d7a5c11..bc6b4a6 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -135,7 +135,7 @@ void tipc_net_stop(struct net *net)
  tn->own_addr);
rtnl_lock();
tipc_bearer_stop(net);
-   tipc_node_stop(net);
+   tipc_node_stop_net(net);
rtnl_unlock();
 
pr_info("Left network mode\n");
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c
index 234cb93..87c3ffa 100644
--- a/net/tipc/netlink.c
+++ b/net/tipc/netlink.c
@@ -134,6 +134,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
.cmd= TIPC_NL_NAME_TABLE_GET,
.dumpit = tipc_nl_name_table_dump,
.policy = tipc_nl_policy,
+   },
+   {
+   .cmd= TIPC_NL_PEER_REMOVE,
+   .doit   = tipc_nl_peer_rm,
+   .policy = tipc_nl_policy,
}
 };
 
diff --git a/net/tipc/node.c b/net/tipc/node.c
index ee6f93c..7334547 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -378,17 +378,21 @@ static void tipc_node_delete(struct tipc_node *node)
kfree_rcu(node, rcu);
 }
 
-void tipc_node_stop(struct net *net)
+static void tipc_node_stop(struct tipc_node *node)
+{
+   if (del_timer(>timer))
+   tipc_node_put(node);
+   tipc_node_put(node);
+}
+
+void tipc_node_stop_net(struct net *net)
 {
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_node *node, *t_node;
 
spin_lock_bh(>node_list_lock);
-   list_for_each_entry_safe(node, t_node, >node_list, list) {
-   if (del_timer(>timer))
-   tipc_node_put(node);
-   tipc_node_put(node);
-   }
+   list_for_each_entry_safe(node, t_node, >node_list, list)
+   tipc_node_stop(node);
spin_unlock_bh(>node_list_lock);
 }
 
@@ -1508,6 +1512,50 @@ discard:
kfree_skb(skb);
 }
 
+int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info)
+{
+   int err;
+   u32 addr;
+   struct net *net = sock_net(skb->sk);
+   struct nlattr *attrs[TIPC_NLA_NET_MAX + 1];
+   struct tipc_net *tn = net_generic(net, tipc_net_id);
+   struct tipc_node *peer;
+
+   /* We identify the peer by its net */
+   if (!info->attrs[TIPC_NLA_NET])
+   return -EINVAL;
+
+   err = nla_parse_nested(attrs, TIPC_NLA_NET_MAX,
+  info->attrs[TIPC_NLA_NET],
+  tipc_nl_net_policy);
+   if (err)
+   return err;
+
+   if (!attrs[TIPC_NLA_NET_ADDR])
+   return -EINVAL;
+
+   addr = nla_get_u32(attrs[TIPC_NLA_NET_ADDR]);
+
+   spin_lock_bh(>node_list_lock);
+   list_for_each_entry_rcu(peer, >node_list, list) {
+   if (peer->addr != addr)
+   continue;
+
+   if (peer->state == SELF_DOWN_PEER_DOWN ||
+   peer->state == SELF_DOWN_PEER_LEAVING) {
+   tipc_node_stop(peer);
+
+   spin_unlock_bh(>node_list_lock);
+   return 0;
+   }
+   spin_unlock_bh(>node_list_lock);
+   return -EBUSY;
+   }
+   spin_unlock_bh(>node_list_lock);
+
+   return -ENXIO;
+}
+
 int tipc_nl_node_dump(struct sk_buff *skb, struct netlink_callback *cb)
 {
int err;
diff --git a/net/tipc/node.h b/net/tipc/node.h
index f39d9d0..8dfb6ba 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -51,7 +51,7 @@ enum {
 #define TIPC_NODE_CAPABILITIES TIPC_BCAST_SYNCH
 #define INVALID_BEARER_ID -1
 
-void tipc_node_stop(struct net *net);
+void tipc_node_stop_net(struct net *net);
 void tipc_node_check_dest(struct net *net, u32 onode,
  struct tipc_bearer *bearer,
  u16 capabilities, u32 s

[PATCH iproute2 1/2] tipc: fix help text spelling error in node.c

2016-01-05 Thread Richard Alpe
---
 tipc/node.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tipc/node.c b/tipc/node.c
index 163fb74..201fe1a 100644
--- a/tipc/node.c
+++ b/tipc/node.c
@@ -245,7 +245,7 @@ static int cmd_node_get(struct nlmsghdr *nlh, const struct 
cmd *cmd,
 void cmd_node_help(struct cmdl *cmdl)
 {
fprintf(stderr,
-   "Usage: %s media COMMAND [ARGS] ...\n\n"
+   "Usage: %s node COMMAND [ARGS] ...\n\n"
"COMMANDS\n"
" list  - List remote nodes\n"
" get   - Get local node parameters\n"
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-next v2] net: Initialize table in fib result

2015-09-17 Thread Richard Alpe
On 2015-09-16 18:19, Nikolay Aleksandrov wrote:
> The root cause is use of res.table uninitialized.
>> 
>> Thanks to Nikolay for noticing the uninitialized use amongst the maze of
>> gotos.
>> 
>> As Nikolay pointed out the second initialization is not required to fix
>> the oops, but rather to fix a related problem where a valid lookup should
>> be invalidated before creating the rth entry.
>> 
>> Fixes: b7503e0cdb5d ("net: Add FIB table id to rtable")
>> Reported-by: Sergey Senozhatsky <sergey.senozhatsky.w...@gmail.com>
>> Reported-by: Richard Alpe <richard.a...@ericsson.com>
Works for me as well. Thanks!

(Tested-by: Richard Alpe <richard.a...@ericsson.com>)

Regards
Richard
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [linux-next] oops in ip_route_input_noref

2015-09-16 Thread Richard Alpe
On 2015-09-16 11:24, Sergey Senozhatsky wrote:
> Hi,
> 
> 4.3.0-rc1-next-20150916
> 
> oops after removal of rndis usb device
> 
> ...
> 8146c052:   00 
> 8146c053:   0f b6 55 8a movzbl -0x76(%rbp),%edx
> 8146c057:   49 8b bf e8 01 00 00mov0x1e8(%r15),%rdi
> 8146c05e:   45 89 d1mov%r10d,%r9d
> 8146c061:   44 89 f6mov%r14d,%esi
> 8146c064:   44 88 95 70 ff ff ffmov%r10b,-0x90(%rbp)
> 8146c06b:   0f 95 c1setne  %cl
> 8146c06e:   81 ce 00 00 00 80   or $0x8000,%esi
> 8146c074:   41 83 e1 01 and$0x1,%r9d
> 8146c078:   45 31 c0xor%r8d,%r8d
> 8146c07b:   e8 49 d5 ff ff  callq  814695c9 
> 
> 8146c080:   48 85 c0test   %rax,%rax
> 8146c083:   49 89 c5mov%rax,%r13
> 8146c086:   75 0a   jne8146c092 
> 
> 8146c088:   bb 97 ff ff ff  mov$0xff97,%ebx
> 8146c08d:   e9 06 f8 ff ff  jmpq   8146b898 
> 
> 8146c092:   48 c7 40 58 a3 95 46movq   
> $0x814695a3,0x58(%rax)
> 8146c099:   81 
> 8146c09a:   c6 80 a2 00 00 00 01movb   $0x1,0xa2(%rax)
> 8146c0a1:   48 8b 45 98 mov-0x68(%rbp),%rax
> 8146c0a5:   44 8a 95 70 ff ff ffmov-0x90(%rbp),%r10b
> 8146c0ac:   48 85 c0test   %rax,%rax
> 8146c0af:   74 0a   je 8146c0bb 
> 
> 8146c0b1:   8b 40 10mov0x10(%rax),%eax
> ^^^
> 8146c0b4:   41 89 85 b0 00 00 00mov%eax,0xb0(%r13)
> 8146c0bb:   65 ff 05 9e 54 ba 7eincl   %gs:0x7eba549e(%rip)   
>  # 11560 
> 8146c0c2:   80 7d 8a 07 cmpb   $0x7,-0x76(%rbp)
> 8146c0c6:   75 1a   jne8146c0e2 
> 
> 8146c0c8:   41 81 a5 9c 00 00 00andl   $0x7fff,0x9c(%r13)
> 8146c0cf:   ff ff ff 7f 
> 8146c0d3:   f7 db   neg%ebx
> 8146c0d5:   49 c7 45 50 b1 96 46movq   
> $0x814696b1,0x50(%r13)
> 8146c0dc:   81 
> 8146c0dd:   66 41 89 5d 64  mov%bx,0x64(%r13)
> 8146c0e2:   45 84 d2test   %r10b,%r10b
> 8146c0e5:   74 29   je 8146c110 
> 
> 8146c0e7:   0f b6 7d 89 movzbl -0x77(%rbp),%edi
> 8146c0eb:   4c 89 eemov%r13,%rsi
> 8146c0ee:   48 ff c7inc%rdi
> 8146c0f1:   48 6b ff 60 imul   $0x60,%rdi,%rdi
> 8146c0f5:   48 03 7d 90 add-0x70(%rbp),%rdi
> 8146c0f9:   e8 10 d1 ff ff  callq  8146920e 
> 
> 8146c0fe:   84 c0   test   %al,%al
> 8146c100:   75 0e   jne8146c110 
> 
> 8146c102:   66 41 83 4d 60 10   orw$0x10,0x60(%r13)
> 8146c108:   4c 89 efmov%r13,%rdi
> 8146c10b:   e8 7d cc ff ff  callq  81468d8d 
> 
> 8146c110:   4d 89 6c 24 58  mov%r13,0x58(%r12)
> 8146c115:   31 db   xor%ebx,%ebx
> 8146c117:   e9 7c f7 ff ff  jmpq   8146b898 
> 
> 8146c11c:   bb 8f ff ff ff  mov$0xff8f,%ebx
> 8146c121:   c6 45 8a 07 movb   $0x7,-0x76(%rbp)
> 8146c125:   48 c7 45 90 00 00 00movq   $0x0,-0x70(%rbp)
> ...
> 
> addr2line -e vmlinux -i 0x8146c0b1
> net/ipv4/route.c:1815
> net/ipv4/route.c:1905
> 
> 
> which seems to be this line ip_route_input_noref()->ip_route_input_slow():
> ...
> 1813 rth->rt_is_input = 1;
> 1814 if (res.table)
> 1815 rth->rt_table_id = res.table->tb_id;
> 1816
> ...
> 
> 
> added by b7503e0cdb5dbec5d201aa69dc14679b5ae8
> 
> net: Add FIB table id to rtable
> 
> Add the FIB table id to rtable to make the information available for
> IPv4 as it is for IPv6.
> 
> 
>   -ss
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

I to get an Oops in ip_route_input_noref(). It happens occasionally during 
bootup.
KVM environment using virtio driver. Let me know if you need any additional 

Re: [linux-next] oops in ip_route_input_noref

2015-09-16 Thread Richard Alpe
On 2015-09-16 15:07, David Ahern wrote:
> On 9/16/15 5:50 AM, Richard Alpe wrote:
>> On 2015-09-16 11:24, Sergey Senozhatsky wrote:
>>> Hi,
>>>
>>> 4.3.0-rc1-next-20150916
>>>
>>> oops after removal of rndis usb device
> 
> Hi Sergey:
> 
> Is this with KVM or baremetal?
> 
> -8<-
> thanks for the analysis
> 
>>> addr2line -e vmlinux -i 0x8146c0b1
>>> net/ipv4/route.c:1815
>>> net/ipv4/route.c:1905
>>>
>>>
>>> which seems to be this line ip_route_input_noref()->ip_route_input_slow():
>>> ...
>>> 1813 rth->rt_is_input = 1;
>>> 1814 if (res.table)
>>> 1815 rth->rt_table_id = res.table->tb_id;
>>> 1816
>>> ...
>>>
>>>
>>> added by b7503e0cdb5dbec5d201aa69dc14679b5ae8
>>>
>>>  net: Add FIB table id to rtable
>>>
>>>  Add the FIB table id to rtable to make the information available for
>>>  IPv4 as it is for IPv6.
>>>
>>>
>>> -ss
> 
> Hi Richard:
> 
>> I to get an Oops in ip_route_input_noref(). It happens occasionally during 
>> bootup.
>> KVM environment using virtio driver. Let me know if you need any additional 
>> info or
>> if you want me to try to bisect it.
>>
>> Starting network...
>> ...
>> [0.877040] BUG: unable to handle kernel NULL pointer dereference at 
>> 0056
>> [0.877597] IP: [] ip_route_input_noref+0x1a2/0xb00
> 
> Can you send me your kernel config and qemu command line? KVM with virtio 
> networking is a primary test vehicle, and I did not encounter this at all.
Sure thing. Not sure how ppl normally provide files on netdev but I'm just going
to go ahead and paste them here :)

$ ps aux | grep kvm
qemu-system-x86_64 -enable-kvm -name tipc-medium-node1 -S -machine 
pc-0.14,accel=kvm,usb=off -m 1024 -realtime mlock=off -smp 
2,sockets=2,cores=1,threads=1 -uuid cdec478a-5f0d-49f1-b25e-fac4ca0b290c 
-no-user-config -nodefaults -chardev 
socket,id=charmonitor,path=/var/lib/libvirt/qemu/tipc-medium-node1.monitor,server,nowait
 -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown 
-boot order=n,menu=on,strict=on -device 
piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -netdev tap,fd=25,id=hostnet0 
-device e1000,netdev=hostnet0,id=net0,mac=00:0f:ff:10:04:01,bus=pci.0,addr=0x3 
-chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 
-vnc 127.0.0.1:28101 -device cirrus-vga,id=video0,bus=pci.0,addr=0x2 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 -msg timestamp=on

$ cat .config
#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 3.12.28 Kernel Configuration
#
CONFIG_64BIT=y
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CPU_AUTOPROBE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ZONE_DMA32=y
CONFIG_AUDIT_ARCH=y
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_X86_64_SMP=y
CONFIG_X86_HT=y
CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx 
-fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 
-fcall-saved-r11"
CONFIG_ARCH_CPU_PROBE_RELEASE=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_SUSE_KERNEL=y
# CONFIG_SUSE_KERNEL_SUPPORTED is not set
# CONFIG_SPLIT_PACKAGE is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y

#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
# CONFIG_COMPILE_TEST is not set
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_XZ is not set
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
CONFIG_DEFAULT_HOSTNAME=&qu

Re: [linux-next] oops in ip_route_input_noref

2015-09-16 Thread Richard Alpe
On 2015-09-16 15:53, Richard Alpe wrote:
> On 2015-09-16 15:07, David Ahern wrote:
>> On 9/16/15 5:50 AM, Richard Alpe wrote:
>>> On 2015-09-16 11:24, Sergey Senozhatsky wrote:
>>>> Hi,
>>>>
>>>> 4.3.0-rc1-next-20150916
>>>>
>>>> oops after removal of rndis usb device
>>
>> Hi Sergey:
>>
>> Is this with KVM or baremetal?
>>
>> -8<-
>> thanks for the analysis
>>
>>>> addr2line -e vmlinux -i 0x8146c0b1
>>>> net/ipv4/route.c:1815
>>>> net/ipv4/route.c:1905
>>>>
>>>>
>>>> which seems to be this line ip_route_input_noref()->ip_route_input_slow():
>>>> ...
>>>> 1813 rth->rt_is_input = 1;
>>>> 1814 if (res.table)
>>>> 1815 rth->rt_table_id = res.table->tb_id;
>>>> 1816
>>>> ...
>>>>
>>>>
>>>> added by b7503e0cdb5dbec5d201aa69dc14679b5ae8
>>>>
>>>>  net: Add FIB table id to rtable
>>>>
>>>>  Add the FIB table id to rtable to make the information available for
>>>>  IPv4 as it is for IPv6.
>>>>
>>>>
>>>> -ss
>>
>> Hi Richard:
>>
>>> I to get an Oops in ip_route_input_noref(). It happens occasionally during 
>>> bootup.
>>> KVM environment using virtio driver. Let me know if you need any additional 
>>> info or
>>> if you want me to try to bisect it.
>>>
>>> Starting network...
>>> ...
>>> [0.877040] BUG: unable to handle kernel NULL pointer dereference at 
>>> 0056
>>> [0.877597] IP: [] ip_route_input_noref+0x1a2/0xb00
>>
>> Can you send me your kernel config and qemu command line? KVM with virtio 
>> networking is a primary test vehicle, and I did not encounter this at all.
> Sure thing. Not sure how ppl normally provide files on netdev but I'm just 
> going
> to go ahead and paste them here :)
> 
> $ ps aux | grep kvm
> qemu-system-x86_64 -enable-kvm -name tipc-medium-node1 -S -machine 
> pc-0.14,accel=kvm,usb=off -m 1024 -realtime mlock=off -smp 
> 2,sockets=2,cores=1,threads=1 -uuid cdec478a-5f0d-49f1-b25e-fac4ca0b290c 
> -no-user-config -nodefaults -chardev 
> socket,id=charmonitor,path=/var/lib/libvirt/qemu/tipc-medium-node1.monitor,server,nowait
>  -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown 
> -boot order=n,menu=on,strict=on -device 
> piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -netdev tap,fd=25,id=hostnet0 
> -device 
> e1000,netdev=hostnet0,id=net0,mac=00:0f:ff:10:04:01,bus=pci.0,addr=0x3 
> -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 
> -vnc 127.0.0.1:28101 -device cirrus-vga,id=video0,bus=pci.0,addr=0x2 -device 
> virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 -msg timestamp=on

Sorry about that kvm cmdline was a copy-paste error. Here's the right one using 
virtio.

$ ps aux | grep qemu
qemu-system-x86_64 -enable-kvm -name tipc-large-node16 -S -machine 
pc-0.14,accel=kvm,usb=off -m 1024 -realtime mlock=off -smp 
2,sockets=2,cores=1,threads=1 -uuid 5c2ffa5f-fc39-47a2-9868-9ef93bada31a 
-no-user-config -nodefaults -chardev 
socket,id=charmonitor,path=/var/lib/libvirt/qemu/tipc-large-node16.monitor,server,nowait
 -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown 
-boot order=n,menu=on,strict=on -device 
piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -netdev 
tap,fd=25,id=hostnet0,vhost=on,vhostfd=48 -device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=00:0f:ff:10:05:16,bus=pci.0,addr=0x3 
-chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 
-vnc 127.0.0.1:29116 -device cirrus-vga,id=video0,bus=pci.0,addr=0x2 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 -msg timestamp=on

Regards
Richard

> 
> $ cat .config
> #
> # Automatically generated file; DO NOT EDIT.
> # Linux/x86 3.12.28 Kernel Configuration
> #
> CONFIG_64BIT=y
> CONFIG_X86_64=y
> CONFIG_X86=y
> CONFIG_INSTRUCTION_DECODER=y
> CONFIG_OUTPUT_FORMAT="elf64-x86-64"
> CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
> CONFIG_LOCKDEP_SUPPORT=y
> CONFIG_STACKTRACE_SUPPORT=y
> CONFIG_HAVE_LATENCYTOP_SUPPORT=y
> CONFIG_MMU=y
> CONFIG_NEED_DMA_MAP_STATE=y
> CONFIG_NEED_SG_DMA_LENGTH=y
> CONFIG_GENERIC_ISA_DMA=y
> CONFIG_GENERIC_BUG=y
> CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y
> CONFIG_GENERIC_HWEIGHT=y
> CONFIG_ARCH_MAY_HAVE_PC_FDC=y
> CONFIG_RWSEM_XCHGADD_ALGORITHM=y
> CONFIG_GENERIC_CALIBRATE_DELAY=y
> CONFIG_ARCH_HAS_CPU_RELAX=y

Re: [linux-next] oops in ip_route_input_noref

2015-09-16 Thread Richard Alpe
On 2015-09-16 15:57, David Ahern wrote:
> On 9/16/15 7:53 AM, Richard Alpe wrote:
>>>> I to get an Oops in ip_route_input_noref(). It happens occasionally during 
>>>> bootup.
>>>> KVM environment using virtio driver. Let me know if you need any 
>>>> additional info or
>>>> if you want me to try to bisect it.
>>>>
>>>> Starting network...
>>>> ...
>>>> [0.877040] BUG: unable to handle kernel NULL pointer dereference at 
>>>> 0056
>>>> [0.877597] IP: [] ip_route_input_noref+0x1a2/0xb00
>>>
>>> Can you send me your kernel config and qemu command line? KVM with virtio 
>>> networking is a primary test vehicle, and I did not encounter this at all.
>> Sure thing. Not sure how ppl normally provide files on netdev but I'm just 
>> going
>> to go ahead and paste them here :)
> 
> An attachment for the config is better than inline.
Fantastic day today, I managed to mess up two out of two copy pastes.
Sorry about that.. Here is the proper kconfig as .gz :)

Regards
Richard

> 
>>
>> $ ps aux | grep kvm
>> qemu-system-x86_64 -enable-kvm -name tipc-medium-node1 -S -machine 
>> pc-0.14,accel=kvm,usb=off -m 1024 -realtime mlock=off -smp 
>> 2,sockets=2,cores=1,threads=1 -uuid cdec478a-5f0d-49f1-b25e-fac4ca0b290c 
>> -no-user-config -nodefaults -chardev 
>> socket,id=charmonitor,path=/var/lib/libvirt/qemu/tipc-medium-node1.monitor,server,nowait
>>  -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown 
>> -boot order=n,menu=on,strict=on -device 
>> piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 -netdev tap,fd=25,id=hostnet0 
>> -device 
>> e1000,netdev=hostnet0,id=net0,mac=00:0f:ff:10:04:01,bus=pci.0,addr=0x3 
>> -chardev pty,id=charserial0 -device 
>> isa-serial,chardev=charserial0,id=serial0 -vnc 127.0.0.1:28101 -device 
>> cirrus-vga,id=video0,bus=pci.0,addr=0x2 -device 
>> virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 -msg timestamp=on
>>
>> $ cat .config
>> #
>> # Automatically generated file; DO NOT EDIT.
>> # Linux/x86 3.12.28 Kernel Configuration
>> #
> 
> 3.12.28? That should say this for net-next:
> 
> # Linux/x86 4.2.0 Kernel Configuration
> 
> Or are you reporting a problem with 3.12.28?
> 
> David



config.gz
Description: application/gzip


Re: [PATCH iproute2] tipc: introduce TIPC configuration tool

2015-06-04 Thread Richard Alpe
On 2015-06-04 12:23, Pavel Simerda wrote:
 - Original Message -
 From: Stephen Hemminger step...@networkplumber.org
 To: richard alpe richard.a...@ericsson.com
 Cc: netdev@vger.kernel.org, tipc-discuss...@lists.sourceforge.net
 Sent: Thursday, May 21, 2015 11:43:40 PM
 Subject: Re: [PATCH iproute2] tipc: introduce TIPC configuration tool

 On Thu, 7 May 2015 15:07:35 +0200
 richard.a...@ericsson.com wrote:

 From: Richard Alpe richard.a...@ericsson.com

 This is the new tipc tool that utilizes the relativly new TIPC netlink API
 in
 the kernel. Introducing this tool into iproute2 has been discussed
 previously.

 For more information about the design decisions of this tool, see the
 README
 file.

 There isn't yet a manpage for the this tool. I will start to write one once
 I
 submitted this for review.

 Richard Alpe (1):
   tipc: add new TIPC configuration tool

 I went ahead and merged this.
 It does add dependency on libmnl which the distribution maintainers will have
 to add to their stuff.
 
 Does the new dependency suggest the whole iproute2 is moving to libmnl?
That is what I was told and the reason I wrote tipc based on libmnl.

Regards
Richard

 Or is
 there a good reason to use an external netlink library as well as an internal 
 one?
 
 Cheers,
 
 Pavel
 


 --
 To unsubscribe from this list: send the line unsubscribe netdev in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html