#include <net/phonet/phonet.h>
#include <net/phonet/pn_dev.h>
-static struct net_proto_family phonet_proto_family;
-static struct phonet_protocol *phonet_proto_get(int protocol);
-static inline void phonet_proto_put(struct phonet_protocol *pp);
+/* Transport protocol registration */
+static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly;
+static DEFINE_SPINLOCK(proto_tab_lock);
+
+static struct phonet_protocol *phonet_proto_get(int protocol)
+{
+ struct phonet_protocol *pp;
+
+ if (protocol >= PHONET_NPROTO)
+ return NULL;
+
+ spin_lock(&proto_tab_lock);
+ pp = proto_tab[protocol];
+ if (pp && !try_module_get(pp->prot->owner))
+ pp = NULL;
+ spin_unlock(&proto_tab_lock);
+
+ return pp;
+}
+
+static inline void phonet_proto_put(struct phonet_protocol *pp)
+{
+ module_put(pp->prot->owner);
+}
/* protocol family functions */
struct phonet_protocol *pnp;
int err;
- if (net != &init_net)
- return -EAFNOSUPPORT;
-
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
ph = pn_hdr(skb);
- if (phonet_address_get(skb->dev, ph->pn_rdev) != ph->pn_rdev)
- return 0; /* we are not the destination */
if (ph->pn_res == PN_PREFIX && !pskb_may_pull(skb, 5))
return 0;
if (ph->pn_res == PN_COMMGR) /* indications */
struct packet_type *pkttype,
struct net_device *orig_dev)
{
+ struct net *net = dev_net(dev);
struct phonethdr *ph;
- struct sock *sk;
struct sockaddr_pn sa;
u16 len;
- if (dev_net(dev) != &init_net)
- goto out;
-
/* check we have at least a full Phonet header */
if (!pskb_pull(skb, sizeof(struct phonethdr)))
goto out;
skb_reset_transport_header(skb);
pn_skb_get_dst_sockaddr(skb, &sa);
- if (pn_sockaddr_get_addr(&sa) == 0)
- goto out; /* currently, we cannot be device 0 */
- sk = pn_find_sock_by_sa(&sa);
- if (sk == NULL) {
+ /* check if we are the destination */
+ if (phonet_address_lookup(net, pn_sockaddr_get_addr(&sa)) == 0) {
+ /* Phonet packet input */
+ struct sock *sk = pn_find_sock_by_sa(net, &sa);
+
+ if (sk)
+ return sk_receive_skb(sk, skb, 0);
+
if (can_respond(skb)) {
send_obj_unreachable(skb);
send_reset_indications(skb);
}
- goto out;
}
- /* Push data to the socket (or other sockets connected to it). */
- return sk_receive_skb(sk, skb, 0);
-
out:
kfree_skb(skb);
return NET_RX_DROP;
}
-static struct packet_type phonet_packet_type = {
- .type = __constant_htons(ETH_P_PHONET),
- .dev = NULL,
+static struct packet_type phonet_packet_type __read_mostly = {
+ .type = cpu_to_be16(ETH_P_PHONET),
.func = phonet_rcv,
};
-/* Transport protocol registration */
-static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly;
-static DEFINE_SPINLOCK(proto_tab_lock);
-
int __init_or_module phonet_proto_register(int protocol,
struct phonet_protocol *pp)
{
}
EXPORT_SYMBOL(phonet_proto_unregister);
-static struct phonet_protocol *phonet_proto_get(int protocol)
-{
- struct phonet_protocol *pp;
-
- if (protocol >= PHONET_NPROTO)
- return NULL;
-
- spin_lock(&proto_tab_lock);
- pp = proto_tab[protocol];
- if (pp && !try_module_get(pp->prot->owner))
- pp = NULL;
- spin_unlock(&proto_tab_lock);
-
- return pp;
-}
-
-static inline void phonet_proto_put(struct phonet_protocol *pp)
-{
- module_put(pp->prot->owner);
-}
-
/* Module registration */
static int __init phonet_init(void)
{
int err;
+ err = phonet_device_init();
+ if (err)
+ return err;
+
err = sock_register(&phonet_proto_family);
if (err) {
printk(KERN_ALERT
"phonet protocol family initialization failed\n");
- return err;
+ goto err_sock;
}
- phonet_device_init();
dev_add_pack(&phonet_packet_type);
- phonet_netlink_register();
phonet_sysctl_init();
err = isi_register();
phonet_sysctl_exit();
sock_unregister(PF_PHONET);
dev_remove_pack(&phonet_packet_type);
+err_sock:
phonet_device_exit();
return err;
}