* [PATCH net-next 0/5] Phonet: basic routing support @ 2009-10-14 10:47 Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 1/5] Phonet: deliver broadcast packets to broadcast sockets Rémi Denis-Courmont 2009-10-14 22:08 ` [PATCH net-next 0/5] Phonet: basic routing support David Miller 0 siblings, 2 replies; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-14 10:47 UTC (permalink / raw) To: netdev Hello, This patchset provides rudimentary support for routing Phonet packets. Configuration is done with the common rtnetlink infrastructure. This is useful when there is more than one Phonet interface in the same namespace, e.g. a serial bus to a cellular modem and a USB gadget function to a PC. Comments welcome. include/net/phonet/phonet.h | 1 include/net/phonet/pn_dev.h | 6 ++ net/phonet/af_phonet.c | 55 ++++++++++++++++-- net/phonet/pn_dev.c | 131 +++++++++++++++++++++++++++++++++++++++++--- net/phonet/pn_netlink.c | 130 +++++++++++++++++++++++++++++++++++++++++++ net/phonet/socket.c | 21 +++++++ 6 files changed, 333 insertions(+), 11 deletions(-) -- Rémi Denis-Courmont ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/5] Phonet: deliver broadcast packets to broadcast sockets 2009-10-14 10:47 [PATCH net-next 0/5] Phonet: basic routing support Rémi Denis-Courmont @ 2009-10-14 10:48 ` Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 2/5] Phonet: routing table backend Rémi Denis-Courmont 2009-10-14 22:08 ` [PATCH net-next 0/5] Phonet: basic routing support David Miller 1 sibling, 1 reply; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw) To: netdev; +Cc: Rémi Denis-Courmont From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> --- include/net/phonet/phonet.h | 1 + net/phonet/af_phonet.c | 6 ++++++ net/phonet/socket.c | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 0 deletions(-) diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h index d43f71b..fdb05fa 100644 --- a/include/net/phonet/phonet.h +++ b/include/net/phonet/phonet.h @@ -47,6 +47,7 @@ static inline struct pn_sock *pn_sk(struct sock *sk) extern const struct proto_ops phonet_dgram_ops; struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *sa); +void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb); void phonet_get_local_port_range(int *min, int *max); void pn_sock_hash(struct sock *sk); void pn_sock_unhash(struct sock *sk); diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index c711d58..b113fe0 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -369,6 +369,12 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev, pn_skb_get_dst_sockaddr(skb, &sa); + /* check if this is broadcasted */ + if (pn_sockaddr_get_addr(&sa) == PNADDR_BROADCAST) { + pn_deliver_sock_broadcast(net, skb); + goto out; + } + /* check if we are the destination */ if (phonet_address_lookup(net, pn_sockaddr_get_addr(&sa)) == 0) { /* Phonet packet input */ diff --git a/net/phonet/socket.c b/net/phonet/socket.c index aa5b5a9..8c84190 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -94,7 +94,28 @@ struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *spn) spin_unlock_bh(&pnsocks.lock); return rval; +} + +/* Deliver a broadcast packet (only in bottom-half) */ +void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb) +{ + struct hlist_node *node; + struct sock *sknode; + + spin_lock(&pnsocks.lock); + sk_for_each(sknode, node, &pnsocks.hlist) { + struct sk_buff *clone; + + if (!net_eq(sock_net(sknode), net)) + continue; + if (!sock_flag(sknode, SOCK_BROADCAST)) + continue; + clone = skb_clone(skb, GFP_ATOMIC); + if (clone) + sk_receive_skb(sknode, clone, 0); + } + spin_unlock(&pnsocks.lock); } void pn_sock_hash(struct sock *sk) -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 2/5] Phonet: routing table backend 2009-10-14 10:48 ` [PATCH 1/5] Phonet: deliver broadcast packets to broadcast sockets Rémi Denis-Courmont @ 2009-10-14 10:48 ` Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 3/5] Phonet: routing table Netlink interface Rémi Denis-Courmont 0 siblings, 1 reply; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw) To: netdev; +Cc: Rémi Denis-Courmont From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> The Phonet "universe" only has 64 addresses, so we keep a trivial flat routing table. Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> --- include/net/phonet/pn_dev.h | 5 ++ net/phonet/pn_dev.c | 100 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 6 deletions(-) diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h index 44c923c..87b5d81 100644 --- a/include/net/phonet/pn_dev.h +++ b/include/net/phonet/pn_dev.h @@ -47,6 +47,11 @@ u8 phonet_address_get(struct net_device *dev, u8 addr); int phonet_address_lookup(struct net *net, u8 addr); void phonet_address_notify(int event, struct net_device *dev, u8 addr); +int phonet_route_add(struct net_device *dev, u8 daddr); +int phonet_route_del(struct net_device *dev, u8 daddr); +struct net_device *phonet_route_get(struct net *net, u8 daddr); +struct net_device *phonet_route_output(struct net *net, u8 daddr); + #define PN_NO_ADDR 0xff extern const struct file_operations pn_sock_seq_fops; diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 5f42f30..71fffa5 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -33,8 +33,14 @@ #include <net/netns/generic.h> #include <net/phonet/pn_dev.h> +struct phonet_routes { + spinlock_t lock; + struct net_device *table[64]; +}; + struct phonet_net { struct phonet_device_list pndevs; + struct phonet_routes routes; }; int phonet_net_id; @@ -154,10 +160,11 @@ int phonet_address_del(struct net_device *dev, u8 addr) } /* Gets a source address toward a destination, through a interface. */ -u8 phonet_address_get(struct net_device *dev, u8 addr) +u8 phonet_address_get(struct net_device *dev, u8 daddr) { struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); struct phonet_device *pnd; + u8 saddr; spin_lock_bh(&pndevs->lock); pnd = __phonet_get(dev); @@ -165,12 +172,26 @@ u8 phonet_address_get(struct net_device *dev, u8 addr) BUG_ON(bitmap_empty(pnd->addrs, 64)); /* Use same source address as destination, if possible */ - if (!test_bit(addr >> 2, pnd->addrs)) - addr = find_first_bit(pnd->addrs, 64) << 2; + if (test_bit(daddr >> 2, pnd->addrs)) + saddr = daddr; + else + saddr = find_first_bit(pnd->addrs, 64) << 2; } else - addr = PN_NO_ADDR; + saddr = PN_NO_ADDR; spin_unlock_bh(&pndevs->lock); - return addr; + + if (saddr == PN_NO_ADDR) { + /* Fallback to another device */ + struct net_device *def_dev; + + def_dev = phonet_device_get(dev_net(dev)); + if (def_dev) { + if (def_dev != dev) + saddr = phonet_address_get(def_dev, daddr); + dev_put(def_dev); + } + } + return saddr; } int phonet_address_lookup(struct net *net, u8 addr) @@ -246,7 +267,7 @@ static struct notifier_block phonet_device_notifier = { /* Per-namespace Phonet devices handling */ static int phonet_init_net(struct net *net) { - struct phonet_net *pnn = kmalloc(sizeof(*pnn), GFP_KERNEL); + struct phonet_net *pnn = kzalloc(sizeof(*pnn), GFP_KERNEL); if (!pnn) return -ENOMEM; @@ -257,6 +278,7 @@ static int phonet_init_net(struct net *net) INIT_LIST_HEAD(&pnn->pndevs.list); spin_lock_init(&pnn->pndevs.lock); + spin_lock_init(&pnn->routes.lock); net_assign_generic(net, phonet_net_id, pnn); return 0; } @@ -300,3 +322,69 @@ void phonet_device_exit(void) unregister_netdevice_notifier(&phonet_device_notifier); unregister_pernet_gen_device(phonet_net_id, &phonet_net_ops); } + +int phonet_route_add(struct net_device *dev, u8 daddr) +{ + struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); + struct phonet_routes *routes = &pnn->routes; + int err = -EEXIST; + + daddr = daddr >> 2; + spin_lock_bh(&routes->lock); + if (routes->table[daddr] == NULL) { + routes->table[daddr] = dev; + dev_hold(dev); + err = 0; + } + spin_unlock_bh(&routes->lock); + return err; +} + +int phonet_route_del(struct net_device *dev, u8 daddr) +{ + struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); + struct phonet_routes *routes = &pnn->routes; + int err = -ENOENT; + + daddr = daddr >> 2; + spin_lock_bh(&routes->lock); + if (dev == routes->table[daddr]) { + routes->table[daddr] = NULL; + dev_put(dev); + err = 0; + } + spin_unlock_bh(&routes->lock); + return err; +} + +struct net_device *phonet_route_get(struct net *net, u8 daddr) +{ + struct phonet_net *pnn = net_generic(net, phonet_net_id); + struct phonet_routes *routes = &pnn->routes; + struct net_device *dev; + + ASSERT_RTNL(); /* no need to hold the device */ + + daddr >>= 2; + spin_lock_bh(&routes->lock); + dev = routes->table[daddr]; + spin_unlock_bh(&routes->lock); + return dev; +} + +struct net_device *phonet_route_output(struct net *net, u8 daddr) +{ + struct phonet_net *pnn = net_generic(net, phonet_net_id); + struct phonet_routes *routes = &pnn->routes; + struct net_device *dev; + + spin_lock_bh(&routes->lock); + dev = routes->table[daddr >> 2]; + if (dev) + dev_hold(dev); + spin_unlock_bh(&routes->lock); + + if (!dev) + dev = phonet_device_get(net); /* Default route */ + return dev; +} -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/5] Phonet: routing table Netlink interface 2009-10-14 10:48 ` [PATCH 2/5] Phonet: routing table backend Rémi Denis-Courmont @ 2009-10-14 10:48 ` Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 4/5] Phonet: route outgoing packets Rémi Denis-Courmont 0 siblings, 1 reply; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw) To: netdev; +Cc: Rémi Denis-Courmont From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> --- include/net/phonet/pn_dev.h | 1 + net/phonet/pn_dev.c | 31 ++++++++++ net/phonet/pn_netlink.c | 130 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 0 deletions(-) diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h index 87b5d81..afa7def 100644 --- a/include/net/phonet/pn_dev.h +++ b/include/net/phonet/pn_dev.h @@ -49,6 +49,7 @@ void phonet_address_notify(int event, struct net_device *dev, u8 addr); int phonet_route_add(struct net_device *dev, u8 daddr); int phonet_route_del(struct net_device *dev, u8 daddr); +void rtm_phonet_notify(int event, struct net_device *dev, u8 dst); struct net_device *phonet_route_get(struct net *net, u8 daddr); struct net_device *phonet_route_output(struct net *net, u8 daddr); diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 71fffa5..6d64fda 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -240,6 +240,27 @@ static int phonet_device_autoconf(struct net_device *dev) return 0; } +static void phonet_route_autodel(struct net_device *dev) +{ + struct phonet_net *pnn = net_generic(dev_net(dev), phonet_net_id); + unsigned i; + DECLARE_BITMAP(deleted, 64); + + /* Remove left-over Phonet routes */ + bitmap_zero(deleted, 64); + spin_lock_bh(&pnn->routes.lock); + for (i = 0; i < 64; i++) + if (dev == pnn->routes.table[i]) { + set_bit(i, deleted); + pnn->routes.table[i] = NULL; + dev_put(dev); + } + spin_unlock_bh(&pnn->routes.lock); + for (i = find_first_bit(deleted, 64); i < 64; + i = find_next_bit(deleted, 64, i + 1)) + rtm_phonet_notify(RTM_DELROUTE, dev, i); +} + /* notify Phonet of device events */ static int phonet_device_notify(struct notifier_block *me, unsigned long what, void *arg) @@ -253,6 +274,7 @@ static int phonet_device_notify(struct notifier_block *me, unsigned long what, break; case NETDEV_UNREGISTER: phonet_device_destroy(dev); + phonet_route_autodel(dev); break; } return 0; @@ -287,10 +309,19 @@ static void phonet_exit_net(struct net *net) { struct phonet_net *pnn = net_generic(net, phonet_net_id); struct net_device *dev; + unsigned i; rtnl_lock(); for_each_netdev(net, dev) phonet_device_destroy(dev); + + for (i = 0; i < 64; i++) { + dev = pnn->routes.table[i]; + if (dev) { + rtm_phonet_notify(RTM_DELROUTE, dev, i); + dev_put(dev); + } + } rtnl_unlock(); proc_net_remove(net, "phonet"); diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index d21fd35..d8f5d3f 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c @@ -29,6 +29,8 @@ #include <net/sock.h> #include <net/phonet/pn_dev.h> +/* Device address handling */ + static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr, u32 pid, u32 seq, int event); @@ -160,6 +162,131 @@ out: return skb->len; } +/* Routes handling */ + +static int fill_route(struct sk_buff *skb, struct net_device *dev, u8 dst, + u32 pid, u32 seq, int event) +{ + struct rtmsg *rtm; + struct nlmsghdr *nlh; + + nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), 0); + if (nlh == NULL) + return -EMSGSIZE; + + rtm = nlmsg_data(nlh); + rtm->rtm_family = AF_PHONET; + rtm->rtm_dst_len = 6; + rtm->rtm_src_len = 0; + rtm->rtm_tos = 0; + rtm->rtm_table = RT_TABLE_MAIN; + rtm->rtm_protocol = RTPROT_STATIC; + rtm->rtm_scope = RT_SCOPE_UNIVERSE; + rtm->rtm_type = RTN_UNICAST; + rtm->rtm_flags = 0; + NLA_PUT_U8(skb, RTA_DST, dst); + NLA_PUT_U32(skb, RTA_OIF, dev->ifindex); + return nlmsg_end(skb, nlh); + +nla_put_failure: + nlmsg_cancel(skb, nlh); + return -EMSGSIZE; +} + +void rtm_phonet_notify(int event, struct net_device *dev, u8 dst) +{ + struct sk_buff *skb; + int err = -ENOBUFS; + + skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) + + nla_total_size(1) + nla_total_size(4), GFP_KERNEL); + if (skb == NULL) + goto errout; + err = fill_route(skb, dev, dst, 0, 0, event); + if (err < 0) { + WARN_ON(err == -EMSGSIZE); + kfree_skb(skb); + goto errout; + } + rtnl_notify(skb, dev_net(dev), 0, + RTNLGRP_PHONET_ROUTE, NULL, GFP_KERNEL); + return; +errout: + if (err < 0) + rtnl_set_sk_err(dev_net(dev), RTNLGRP_PHONET_ROUTE, err); +} + +static const struct nla_policy rtm_phonet_policy[RTA_MAX+1] = { + [RTA_DST] = { .type = NLA_U8 }, + [RTA_OIF] = { .type = NLA_U32 }, +}; + +static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr) +{ + struct net *net = sock_net(skb->sk); + struct nlattr *tb[RTA_MAX+1]; + struct net_device *dev; + struct rtmsg *rtm; + int err; + u8 dst; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + ASSERT_RTNL(); + + err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_phonet_policy); + if (err < 0) + return err; + + rtm = nlmsg_data(nlh); + if (rtm->rtm_table != RT_TABLE_MAIN || rtm->rtm_type != RTN_UNICAST) + return -EINVAL; + if (tb[RTA_DST] == NULL || tb[RTA_OIF] == NULL) + return -EINVAL; + dst = nla_get_u8(tb[RTA_DST]); + if (dst & 3) /* Phonet addresses only have 6 high-order bits */ + return -EINVAL; + + dev = __dev_get_by_index(net, nla_get_u32(tb[RTA_OIF])); + if (dev == NULL) + return -ENODEV; + + if (nlh->nlmsg_type == RTM_NEWROUTE) + err = phonet_route_add(dev, dst); + else + err = phonet_route_del(dev, dst); + if (!err) + rtm_phonet_notify(nlh->nlmsg_type, dev, dst); + return err; +} + +static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb) +{ + struct net *net = sock_net(skb->sk); + u8 addr, addr_idx = 0, addr_start_idx = cb->args[0]; + + for (addr = 0; addr < 64; addr++) { + struct net_device *dev; + + dev = phonet_route_get(net, addr << 2); + if (!dev) + continue; + + if (addr_idx++ < addr_start_idx) + continue; + if (fill_route(skb, dev, addr << 2, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_NEWROUTE)) + goto out; + } + +out: + cb->args[0] = addr_idx; + cb->args[1] = 0; + + return skb->len; +} + int __init phonet_netlink_register(void) { int err = __rtnl_register(PF_PHONET, RTM_NEWADDR, addr_doit, NULL); @@ -169,5 +296,8 @@ int __init phonet_netlink_register(void) /* Further __rtnl_register() cannot fail */ __rtnl_register(PF_PHONET, RTM_DELADDR, addr_doit, NULL); __rtnl_register(PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit); + __rtnl_register(PF_PHONET, RTM_NEWROUTE, route_doit, NULL); + __rtnl_register(PF_PHONET, RTM_DELROUTE, route_doit, NULL); + __rtnl_register(PF_PHONET, RTM_GETROUTE, NULL, route_dumpit); return 0; } -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 4/5] Phonet: route outgoing packets 2009-10-14 10:48 ` [PATCH 3/5] Phonet: routing table Netlink interface Rémi Denis-Courmont @ 2009-10-14 10:48 ` Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 5/5] Phonet: forward incoming packets Rémi Denis-Courmont 0 siblings, 1 reply; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw) To: netdev; +Cc: Rémi Denis-Courmont From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> --- net/phonet/af_phonet.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index b113fe0..cc2eef1 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -190,9 +190,8 @@ static int pn_send(struct sk_buff *skb, struct net_device *dev, skb->priority = 0; skb->dev = dev; - if (pn_addr(src) == pn_addr(dst)) { + if (skb->pkt_type == PACKET_LOOPBACK) { skb_reset_mac_header(skb); - skb->pkt_type = PACKET_LOOPBACK; skb_orphan(skb); if (irq) netif_rx(skb); @@ -222,6 +221,9 @@ static int pn_raw_send(const void *data, int len, struct net_device *dev, if (skb == NULL) return -ENOMEM; + if (phonet_address_lookup(dev_net(dev), pn_addr(dst)) == 0) + skb->pkt_type = PACKET_LOOPBACK; + skb_reserve(skb, MAX_PHONET_HEADER); __skb_put(skb, len); skb_copy_to_linear_data(skb, data, len); @@ -235,6 +237,7 @@ static int pn_raw_send(const void *data, int len, struct net_device *dev, int pn_skb_send(struct sock *sk, struct sk_buff *skb, const struct sockaddr_pn *target) { + struct net *net = sock_net(sk); struct net_device *dev; struct pn_sock *pn = pn_sk(sk); int err; @@ -243,9 +246,13 @@ int pn_skb_send(struct sock *sk, struct sk_buff *skb, err = -EHOSTUNREACH; if (sk->sk_bound_dev_if) - dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); - else - dev = phonet_device_get(sock_net(sk)); + dev = dev_get_by_index(net, sk->sk_bound_dev_if); + else if (phonet_address_lookup(net, daddr) == 0) { + dev = phonet_device_get(net); + skb->pkt_type = PACKET_LOOPBACK; + } else + dev = phonet_route_output(net, daddr); + if (!dev || !(dev->flags & IFF_UP)) goto drop; -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 5/5] Phonet: forward incoming packets 2009-10-14 10:48 ` [PATCH 4/5] Phonet: route outgoing packets Rémi Denis-Courmont @ 2009-10-14 10:48 ` Rémi Denis-Courmont 0 siblings, 0 replies; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-14 10:48 UTC (permalink / raw) To: netdev; +Cc: Rémi Denis-Courmont From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> --- net/phonet/af_phonet.c | 32 ++++++++++++++++++++++++++++++++ 1 files changed, 32 insertions(+), 0 deletions(-) diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index cc2eef1..66737aa 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -394,6 +394,38 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev, send_obj_unreachable(skb); send_reset_indications(skb); } + } else if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) + goto out; /* Race between address deletion and loopback */ + else { + /* Phonet packet routing */ + struct net_device *out_dev; + + out_dev = phonet_route_output(net, pn_sockaddr_get_addr(&sa)); + if (!out_dev) { + LIMIT_NETDEBUG(KERN_WARNING"No Phonet route to %02X\n", + pn_sockaddr_get_addr(&sa)); + goto out; + } + + __skb_push(skb, sizeof(struct phonethdr)); + skb->dev = out_dev; + if (out_dev == dev) { + LIMIT_NETDEBUG(KERN_ERR"Phonet loop to %02X on %s\n", + pn_sockaddr_get_addr(&sa), dev->name); + goto out_dev; + } + /* Some drivers (e.g. TUN) do not allocate HW header space */ + if (skb_cow_head(skb, out_dev->hard_header_len)) + goto out_dev; + + if (dev_hard_header(skb, out_dev, ETH_P_PHONET, NULL, NULL, + skb->len) < 0) + goto out_dev; + dev_queue_xmit(skb); + dev_put(out_dev); + return NET_RX_SUCCESS; +out_dev: + dev_put(out_dev); } out: -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 0/5] Phonet: basic routing support 2009-10-14 10:47 [PATCH net-next 0/5] Phonet: basic routing support Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 1/5] Phonet: deliver broadcast packets to broadcast sockets Rémi Denis-Courmont @ 2009-10-14 22:08 ` David Miller 2009-10-15 12:58 ` Rémi Denis-Courmont 1 sibling, 1 reply; 11+ messages in thread From: David Miller @ 2009-10-14 22:08 UTC (permalink / raw) To: remi; +Cc: netdev From: Rémi Denis-Courmont <remi@remlab.net> Date: Wed, 14 Oct 2009 12:47:34 +0200 > > This patchset provides rudimentary support for routing Phonet packets. > Configuration is done with the common rtnetlink infrastructure. > > This is useful when there is more than one Phonet interface in the same > namespace, > e.g. a serial bus to a cellular modem and a USB gadget function to a PC. Looks good, applied to net-next-2.6, thanks. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next 0/5] Phonet: basic routing support 2009-10-14 22:08 ` [PATCH net-next 0/5] Phonet: basic routing support David Miller @ 2009-10-15 12:58 ` Rémi Denis-Courmont 2009-10-15 13:00 ` [PATCH] Phonet: hold socket before giving it to sk_deliver_skb() Rémi Denis-Courmont 0 siblings, 1 reply; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-15 12:58 UTC (permalink / raw) To: netdev On Wed, 14 Oct 2009 15:08:43 -0700 (PDT), David Miller <davem@davemloft.net> wrote: > From: Rémi Denis-Courmont <remi@remlab.net> > Date: Wed, 14 Oct 2009 12:47:34 +0200 > >> >> This patchset provides rudimentary support for routing Phonet packets. >> Configuration is done with the common rtnetlink infrastructure. >> >> This is useful when there is more than one Phonet interface in the same >> namespace, >> e.g. a serial bus to a cellular modem and a USB gadget function to a PC. > > Looks good, applied to net-next-2.6, thanks. Hmmrr or not. I took an old buggy patchset. Trivial fix follows. Sorry. -- Rémi Denis-Courmont ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] Phonet: hold socket before giving it to sk_deliver_skb() 2009-10-15 12:58 ` Rémi Denis-Courmont @ 2009-10-15 13:00 ` Rémi Denis-Courmont 2009-10-15 14:52 ` Eric Dumazet 2009-10-15 19:29 ` David Miller 0 siblings, 2 replies; 11+ messages in thread From: Rémi Denis-Courmont @ 2009-10-15 13:00 UTC (permalink / raw) To: netdev; +Cc: Rémi Denis-Courmont From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> --- net/phonet/socket.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 8c84190..0412beb 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -112,8 +112,10 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb) continue; clone = skb_clone(skb, GFP_ATOMIC); - if (clone) + if (clone) { + sock_hold(sknode); sk_receive_skb(sknode, clone, 0); + } } spin_unlock(&pnsocks.lock); } -- 1.6.0.4 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] Phonet: hold socket before giving it to sk_deliver_skb() 2009-10-15 13:00 ` [PATCH] Phonet: hold socket before giving it to sk_deliver_skb() Rémi Denis-Courmont @ 2009-10-15 14:52 ` Eric Dumazet 2009-10-15 19:29 ` David Miller 1 sibling, 0 replies; 11+ messages in thread From: Eric Dumazet @ 2009-10-15 14:52 UTC (permalink / raw) To: Rémi Denis-Courmont; +Cc: netdev, Rémi Denis-Courmont Rémi Denis-Courmont a écrit : > From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> > > Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> > --- > net/phonet/socket.c | 4 +++- > 1 files changed, 3 insertions(+), 1 deletions(-) > > diff --git a/net/phonet/socket.c b/net/phonet/socket.c > index 8c84190..0412beb 100644 > --- a/net/phonet/socket.c > +++ b/net/phonet/socket.c > @@ -112,8 +112,10 @@ void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb) > continue; > > clone = skb_clone(skb, GFP_ATOMIC); > - if (clone) > + if (clone) { > + sock_hold(sknode); > sk_receive_skb(sknode, clone, 0); > + } > } > spin_unlock(&pnsocks.lock); > } Indeed sk_receive_skb() does a sock_put(sk) Acked-by: Eric Dumazet <eric.dumazet@gmail.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Phonet: hold socket before giving it to sk_deliver_skb() 2009-10-15 13:00 ` [PATCH] Phonet: hold socket before giving it to sk_deliver_skb() Rémi Denis-Courmont 2009-10-15 14:52 ` Eric Dumazet @ 2009-10-15 19:29 ` David Miller 1 sibling, 0 replies; 11+ messages in thread From: David Miller @ 2009-10-15 19:29 UTC (permalink / raw) To: remi; +Cc: netdev, remi.denis-courmont From: Rémi Denis-Courmont <remi@remlab.net> Date: Thu, 15 Oct 2009 16:00:00 +0300 > From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> > > Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Applied. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2009-10-15 19:29 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-10-14 10:47 [PATCH net-next 0/5] Phonet: basic routing support Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 1/5] Phonet: deliver broadcast packets to broadcast sockets Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 2/5] Phonet: routing table backend Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 3/5] Phonet: routing table Netlink interface Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 4/5] Phonet: route outgoing packets Rémi Denis-Courmont 2009-10-14 10:48 ` [PATCH 5/5] Phonet: forward incoming packets Rémi Denis-Courmont 2009-10-14 22:08 ` [PATCH net-next 0/5] Phonet: basic routing support David Miller 2009-10-15 12:58 ` Rémi Denis-Courmont 2009-10-15 13:00 ` [PATCH] Phonet: hold socket before giving it to sk_deliver_skb() Rémi Denis-Courmont 2009-10-15 14:52 ` Eric Dumazet 2009-10-15 19:29 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).