Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * DECnet       An implementation of the DECnet protocol suite for the LINUX
0004  *              operating system.  DECnet is implemented using the  BSD Socket
0005  *              interface as the means of communication with the user level.
0006  *
0007  *              DECnet Neighbour Functions (Adjacency Database and
0008  *                                                        On-Ethernet Cache)
0009  *
0010  * Author:      Steve Whitehouse <SteveW@ACM.org>
0011  *
0012  *
0013  * Changes:
0014  *     Steve Whitehouse     : Fixed router listing routine
0015  *     Steve Whitehouse     : Added error_report functions
0016  *     Steve Whitehouse     : Added default router detection
0017  *     Steve Whitehouse     : Hop counts in outgoing messages
0018  *     Steve Whitehouse     : Fixed src/dst in outgoing messages so
0019  *                            forwarding now stands a good chance of
0020  *                            working.
0021  *     Steve Whitehouse     : Fixed neighbour states (for now anyway).
0022  *     Steve Whitehouse     : Made error_report functions dummies. This
0023  *                            is not the right place to return skbs.
0024  *     Steve Whitehouse     : Convert to seq_file
0025  *
0026  */
0027 
0028 #include <linux/net.h>
0029 #include <linux/module.h>
0030 #include <linux/socket.h>
0031 #include <linux/if_arp.h>
0032 #include <linux/slab.h>
0033 #include <linux/if_ether.h>
0034 #include <linux/init.h>
0035 #include <linux/proc_fs.h>
0036 #include <linux/string.h>
0037 #include <linux/netfilter_decnet.h>
0038 #include <linux/spinlock.h>
0039 #include <linux/seq_file.h>
0040 #include <linux/rcupdate.h>
0041 #include <linux/jhash.h>
0042 #include <linux/atomic.h>
0043 #include <net/net_namespace.h>
0044 #include <net/neighbour.h>
0045 #include <net/dst.h>
0046 #include <net/flow.h>
0047 #include <net/dn.h>
0048 #include <net/dn_dev.h>
0049 #include <net/dn_neigh.h>
0050 #include <net/dn_route.h>
0051 
0052 static int dn_neigh_construct(struct neighbour *);
0053 static void dn_neigh_error_report(struct neighbour *, struct sk_buff *);
0054 static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb);
0055 
0056 /*
0057  * Operations for adding the link layer header.
0058  */
0059 static const struct neigh_ops dn_neigh_ops = {
0060     .family =       AF_DECnet,
0061     .error_report =     dn_neigh_error_report,
0062     .output =       dn_neigh_output,
0063     .connected_output = dn_neigh_output,
0064 };
0065 
0066 static u32 dn_neigh_hash(const void *pkey,
0067              const struct net_device *dev,
0068              __u32 *hash_rnd)
0069 {
0070     return jhash_2words(*(__u16 *)pkey, 0, hash_rnd[0]);
0071 }
0072 
0073 static bool dn_key_eq(const struct neighbour *neigh, const void *pkey)
0074 {
0075     return neigh_key_eq16(neigh, pkey);
0076 }
0077 
0078 struct neigh_table dn_neigh_table = {
0079     .family =           PF_DECnet,
0080     .entry_size =           NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)),
0081     .key_len =          sizeof(__le16),
0082     .protocol =         cpu_to_be16(ETH_P_DNA_RT),
0083     .hash =             dn_neigh_hash,
0084     .key_eq =           dn_key_eq,
0085     .constructor =          dn_neigh_construct,
0086     .id =               "dn_neigh_cache",
0087     .parms ={
0088         .tbl =          &dn_neigh_table,
0089         .reachable_time =   30 * HZ,
0090         .data = {
0091             [NEIGH_VAR_MCAST_PROBES] = 0,
0092             [NEIGH_VAR_UCAST_PROBES] = 0,
0093             [NEIGH_VAR_APP_PROBES] = 0,
0094             [NEIGH_VAR_RETRANS_TIME] = 1 * HZ,
0095             [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ,
0096             [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
0097             [NEIGH_VAR_INTERVAL_PROBE_TIME_MS] = 5 * HZ,
0098             [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
0099             [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX,
0100             [NEIGH_VAR_PROXY_QLEN] = 0,
0101             [NEIGH_VAR_ANYCAST_DELAY] = 0,
0102             [NEIGH_VAR_PROXY_DELAY] = 0,
0103             [NEIGH_VAR_LOCKTIME] = 1 * HZ,
0104         },
0105     },
0106     .gc_interval =          30 * HZ,
0107     .gc_thresh1 =           128,
0108     .gc_thresh2 =           512,
0109     .gc_thresh3 =           1024,
0110 };
0111 
0112 static int dn_neigh_construct(struct neighbour *neigh)
0113 {
0114     struct net_device *dev = neigh->dev;
0115     struct dn_neigh *dn = container_of(neigh, struct dn_neigh, n);
0116     struct dn_dev *dn_db;
0117     struct neigh_parms *parms;
0118 
0119     rcu_read_lock();
0120     dn_db = rcu_dereference(dev->dn_ptr);
0121     if (dn_db == NULL) {
0122         rcu_read_unlock();
0123         return -EINVAL;
0124     }
0125 
0126     parms = dn_db->neigh_parms;
0127     if (!parms) {
0128         rcu_read_unlock();
0129         return -EINVAL;
0130     }
0131 
0132     __neigh_parms_put(neigh->parms);
0133     neigh->parms = neigh_parms_clone(parms);
0134     rcu_read_unlock();
0135 
0136     neigh->ops = &dn_neigh_ops;
0137     neigh->nud_state = NUD_NOARP;
0138     neigh->output = neigh->ops->connected_output;
0139 
0140     if ((dev->type == ARPHRD_IPGRE) || (dev->flags & IFF_POINTOPOINT))
0141         memcpy(neigh->ha, dev->broadcast, dev->addr_len);
0142     else if ((dev->type == ARPHRD_ETHER) || (dev->type == ARPHRD_LOOPBACK))
0143         dn_dn2eth(neigh->ha, dn->addr);
0144     else {
0145         net_dbg_ratelimited("Trying to create neigh for hw %d\n",
0146                     dev->type);
0147         return -EINVAL;
0148     }
0149 
0150     /*
0151      * Make an estimate of the remote block size by assuming that its
0152      * two less then the device mtu, which it true for ethernet (and
0153      * other things which support long format headers) since there is
0154      * an extra length field (of 16 bits) which isn't part of the
0155      * ethernet headers and which the DECnet specs won't admit is part
0156      * of the DECnet routing headers either.
0157      *
0158      * If we over estimate here its no big deal, the NSP negotiations
0159      * will prevent us from sending packets which are too large for the
0160      * remote node to handle. In any case this figure is normally updated
0161      * by a hello message in most cases.
0162      */
0163     dn->blksize = dev->mtu - 2;
0164 
0165     return 0;
0166 }
0167 
0168 static void dn_neigh_error_report(struct neighbour *neigh, struct sk_buff *skb)
0169 {
0170     printk(KERN_DEBUG "dn_neigh_error_report: called\n");
0171     kfree_skb(skb);
0172 }
0173 
0174 static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb)
0175 {
0176     struct dst_entry *dst = skb_dst(skb);
0177     struct dn_route *rt = (struct dn_route *)dst;
0178     struct net_device *dev = neigh->dev;
0179     char mac_addr[ETH_ALEN];
0180     unsigned int seq;
0181     int err;
0182 
0183     dn_dn2eth(mac_addr, rt->rt_local_src);
0184     do {
0185         seq = read_seqbegin(&neigh->ha_lock);
0186         err = dev_hard_header(skb, dev, ntohs(skb->protocol),
0187                       neigh->ha, mac_addr, skb->len);
0188     } while (read_seqretry(&neigh->ha_lock, seq));
0189 
0190     if (err >= 0)
0191         err = dev_queue_xmit(skb);
0192     else {
0193         kfree_skb(skb);
0194         err = -EINVAL;
0195     }
0196     return err;
0197 }
0198 
0199 static int dn_neigh_output_packet(struct net *net, struct sock *sk, struct sk_buff *skb)
0200 {
0201     struct dst_entry *dst = skb_dst(skb);
0202     struct dn_route *rt = (struct dn_route *)dst;
0203     struct neighbour *neigh = rt->n;
0204 
0205     return neigh->output(neigh, skb);
0206 }
0207 
0208 /*
0209  * For talking to broadcast devices: Ethernet & PPP
0210  */
0211 static int dn_long_output(struct neighbour *neigh, struct sock *sk,
0212               struct sk_buff *skb)
0213 {
0214     struct net_device *dev = neigh->dev;
0215     int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3;
0216     unsigned char *data;
0217     struct dn_long_packet *lp;
0218     struct dn_skb_cb *cb = DN_SKB_CB(skb);
0219 
0220 
0221     if (skb_headroom(skb) < headroom) {
0222         struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
0223         if (skb2 == NULL) {
0224             net_crit_ratelimited("dn_long_output: no memory\n");
0225             kfree_skb(skb);
0226             return -ENOBUFS;
0227         }
0228         consume_skb(skb);
0229         skb = skb2;
0230         net_info_ratelimited("dn_long_output: Increasing headroom\n");
0231     }
0232 
0233     data = skb_push(skb, sizeof(struct dn_long_packet) + 3);
0234     lp = (struct dn_long_packet *)(data+3);
0235 
0236     *((__le16 *)data) = cpu_to_le16(skb->len - 2);
0237     *(data + 2) = 1 | DN_RT_F_PF; /* Padding */
0238 
0239     lp->msgflg   = DN_RT_PKT_LONG|(cb->rt_flags&(DN_RT_F_IE|DN_RT_F_RQR|DN_RT_F_RTS));
0240     lp->d_area   = lp->d_subarea = 0;
0241     dn_dn2eth(lp->d_id, cb->dst);
0242     lp->s_area   = lp->s_subarea = 0;
0243     dn_dn2eth(lp->s_id, cb->src);
0244     lp->nl2      = 0;
0245     lp->visit_ct = cb->hops & 0x3f;
0246     lp->s_class  = 0;
0247     lp->pt       = 0;
0248 
0249     skb_reset_network_header(skb);
0250 
0251     return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING,
0252                &init_net, sk, skb, NULL, neigh->dev,
0253                dn_neigh_output_packet);
0254 }
0255 
0256 /*
0257  * For talking to pointopoint and multidrop devices: DDCMP and X.25
0258  */
0259 static int dn_short_output(struct neighbour *neigh, struct sock *sk,
0260                struct sk_buff *skb)
0261 {
0262     struct net_device *dev = neigh->dev;
0263     int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
0264     struct dn_short_packet *sp;
0265     unsigned char *data;
0266     struct dn_skb_cb *cb = DN_SKB_CB(skb);
0267 
0268 
0269     if (skb_headroom(skb) < headroom) {
0270         struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
0271         if (skb2 == NULL) {
0272             net_crit_ratelimited("dn_short_output: no memory\n");
0273             kfree_skb(skb);
0274             return -ENOBUFS;
0275         }
0276         consume_skb(skb);
0277         skb = skb2;
0278         net_info_ratelimited("dn_short_output: Increasing headroom\n");
0279     }
0280 
0281     data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
0282     *((__le16 *)data) = cpu_to_le16(skb->len - 2);
0283     sp = (struct dn_short_packet *)(data+2);
0284 
0285     sp->msgflg     = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
0286     sp->dstnode    = cb->dst;
0287     sp->srcnode    = cb->src;
0288     sp->forward    = cb->hops & 0x3f;
0289 
0290     skb_reset_network_header(skb);
0291 
0292     return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING,
0293                &init_net, sk, skb, NULL, neigh->dev,
0294                dn_neigh_output_packet);
0295 }
0296 
0297 /*
0298  * For talking to DECnet phase III nodes
0299  * Phase 3 output is the same as short output, execpt that
0300  * it clears the area bits before transmission.
0301  */
0302 static int dn_phase3_output(struct neighbour *neigh, struct sock *sk,
0303                 struct sk_buff *skb)
0304 {
0305     struct net_device *dev = neigh->dev;
0306     int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
0307     struct dn_short_packet *sp;
0308     unsigned char *data;
0309     struct dn_skb_cb *cb = DN_SKB_CB(skb);
0310 
0311     if (skb_headroom(skb) < headroom) {
0312         struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
0313         if (skb2 == NULL) {
0314             net_crit_ratelimited("dn_phase3_output: no memory\n");
0315             kfree_skb(skb);
0316             return -ENOBUFS;
0317         }
0318         consume_skb(skb);
0319         skb = skb2;
0320         net_info_ratelimited("dn_phase3_output: Increasing headroom\n");
0321     }
0322 
0323     data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
0324     *((__le16 *)data) = cpu_to_le16(skb->len - 2);
0325     sp = (struct dn_short_packet *)(data + 2);
0326 
0327     sp->msgflg   = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
0328     sp->dstnode  = cb->dst & cpu_to_le16(0x03ff);
0329     sp->srcnode  = cb->src & cpu_to_le16(0x03ff);
0330     sp->forward  = cb->hops & 0x3f;
0331 
0332     skb_reset_network_header(skb);
0333 
0334     return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING,
0335                &init_net, sk, skb, NULL, neigh->dev,
0336                dn_neigh_output_packet);
0337 }
0338 
0339 int dn_to_neigh_output(struct net *net, struct sock *sk, struct sk_buff *skb)
0340 {
0341     struct dst_entry *dst = skb_dst(skb);
0342     struct dn_route *rt = (struct dn_route *) dst;
0343     struct neighbour *neigh = rt->n;
0344     struct dn_neigh *dn = container_of(neigh, struct dn_neigh, n);
0345     struct dn_dev *dn_db;
0346     bool use_long;
0347 
0348     rcu_read_lock();
0349     dn_db = rcu_dereference(neigh->dev->dn_ptr);
0350     if (dn_db == NULL) {
0351         rcu_read_unlock();
0352         return -EINVAL;
0353     }
0354     use_long = dn_db->use_long;
0355     rcu_read_unlock();
0356 
0357     if (dn->flags & DN_NDFLAG_P3)
0358         return dn_phase3_output(neigh, sk, skb);
0359     if (use_long)
0360         return dn_long_output(neigh, sk, skb);
0361     else
0362         return dn_short_output(neigh, sk, skb);
0363 }
0364 
0365 /*
0366  * Unfortunately, the neighbour code uses the device in its hash
0367  * function, so we don't get any advantage from it. This function
0368  * basically does a neigh_lookup(), but without comparing the device
0369  * field. This is required for the On-Ethernet cache
0370  */
0371 
0372 /*
0373  * Pointopoint link receives a hello message
0374  */
0375 void dn_neigh_pointopoint_hello(struct sk_buff *skb)
0376 {
0377     kfree_skb(skb);
0378 }
0379 
0380 /*
0381  * Ethernet router hello message received
0382  */
0383 int dn_neigh_router_hello(struct net *net, struct sock *sk, struct sk_buff *skb)
0384 {
0385     struct rtnode_hello_message *msg = (struct rtnode_hello_message *)skb->data;
0386 
0387     struct neighbour *neigh;
0388     struct dn_neigh *dn;
0389     struct dn_dev *dn_db;
0390     __le16 src;
0391 
0392     src = dn_eth2dn(msg->id);
0393 
0394     neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);
0395 
0396     dn = container_of(neigh, struct dn_neigh, n);
0397 
0398     if (neigh) {
0399         write_lock(&neigh->lock);
0400 
0401         neigh->used = jiffies;
0402         dn_db = rcu_dereference(neigh->dev->dn_ptr);
0403 
0404         if (!(neigh->nud_state & NUD_PERMANENT)) {
0405             neigh->updated = jiffies;
0406 
0407             if (neigh->dev->type == ARPHRD_ETHER)
0408                 memcpy(neigh->ha, &eth_hdr(skb)->h_source, ETH_ALEN);
0409 
0410             dn->blksize  = le16_to_cpu(msg->blksize);
0411             dn->priority = msg->priority;
0412 
0413             dn->flags &= ~DN_NDFLAG_P3;
0414 
0415             switch (msg->iinfo & DN_RT_INFO_TYPE) {
0416             case DN_RT_INFO_L1RT:
0417                 dn->flags &=~DN_NDFLAG_R2;
0418                 dn->flags |= DN_NDFLAG_R1;
0419                 break;
0420             case DN_RT_INFO_L2RT:
0421                 dn->flags |= DN_NDFLAG_R2;
0422             }
0423         }
0424 
0425         /* Only use routers in our area */
0426         if ((le16_to_cpu(src)>>10) == (le16_to_cpu((decnet_address))>>10)) {
0427             if (!dn_db->router) {
0428                 dn_db->router = neigh_clone(neigh);
0429             } else {
0430                 if (msg->priority > container_of(dn_db->router,
0431                                  struct dn_neigh, n)->priority)
0432                     neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
0433             }
0434         }
0435         write_unlock(&neigh->lock);
0436         neigh_release(neigh);
0437     }
0438 
0439     kfree_skb(skb);
0440     return 0;
0441 }
0442 
0443 /*
0444  * Endnode hello message received
0445  */
0446 int dn_neigh_endnode_hello(struct net *net, struct sock *sk, struct sk_buff *skb)
0447 {
0448     struct endnode_hello_message *msg = (struct endnode_hello_message *)skb->data;
0449     struct neighbour *neigh;
0450     struct dn_neigh *dn;
0451     __le16 src;
0452 
0453     src = dn_eth2dn(msg->id);
0454 
0455     neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);
0456 
0457     dn = container_of(neigh, struct dn_neigh, n);
0458 
0459     if (neigh) {
0460         write_lock(&neigh->lock);
0461 
0462         neigh->used = jiffies;
0463 
0464         if (!(neigh->nud_state & NUD_PERMANENT)) {
0465             neigh->updated = jiffies;
0466 
0467             if (neigh->dev->type == ARPHRD_ETHER)
0468                 memcpy(neigh->ha, &eth_hdr(skb)->h_source, ETH_ALEN);
0469             dn->flags   &= ~(DN_NDFLAG_R1 | DN_NDFLAG_R2);
0470             dn->blksize  = le16_to_cpu(msg->blksize);
0471             dn->priority = 0;
0472         }
0473 
0474         write_unlock(&neigh->lock);
0475         neigh_release(neigh);
0476     }
0477 
0478     kfree_skb(skb);
0479     return 0;
0480 }
0481 
0482 static char *dn_find_slot(char *base, int max, int priority)
0483 {
0484     int i;
0485     unsigned char *min = NULL;
0486 
0487     base += 6; /* skip first id */
0488 
0489     for(i = 0; i < max; i++) {
0490         if (!min || (*base < *min))
0491             min = base;
0492         base += 7; /* find next priority */
0493     }
0494 
0495     if (!min)
0496         return NULL;
0497 
0498     return (*min < priority) ? (min - 6) : NULL;
0499 }
0500 
0501 struct elist_cb_state {
0502     struct net_device *dev;
0503     unsigned char *ptr;
0504     unsigned char *rs;
0505     int t, n;
0506 };
0507 
0508 static void neigh_elist_cb(struct neighbour *neigh, void *_info)
0509 {
0510     struct elist_cb_state *s = _info;
0511     struct dn_neigh *dn;
0512 
0513     if (neigh->dev != s->dev)
0514         return;
0515 
0516     dn = container_of(neigh, struct dn_neigh, n);
0517     if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2)))
0518         return;
0519 
0520     if (s->t == s->n)
0521         s->rs = dn_find_slot(s->ptr, s->n, dn->priority);
0522     else
0523         s->t++;
0524     if (s->rs == NULL)
0525         return;
0526 
0527     dn_dn2eth(s->rs, dn->addr);
0528     s->rs += 6;
0529     *(s->rs) = neigh->nud_state & NUD_CONNECTED ? 0x80 : 0x0;
0530     *(s->rs) |= dn->priority;
0531     s->rs++;
0532 }
0533 
0534 int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n)
0535 {
0536     struct elist_cb_state state;
0537 
0538     state.dev = dev;
0539     state.t = 0;
0540     state.n = n;
0541     state.ptr = ptr;
0542     state.rs = ptr;
0543 
0544     neigh_for_each(&dn_neigh_table, neigh_elist_cb, &state);
0545 
0546     return state.t;
0547 }
0548 
0549 
0550 #ifdef CONFIG_PROC_FS
0551 
0552 static inline void dn_neigh_format_entry(struct seq_file *seq,
0553                      struct neighbour *n)
0554 {
0555     struct dn_neigh *dn = container_of(n, struct dn_neigh, n);
0556     char buf[DN_ASCBUF_LEN];
0557 
0558     read_lock(&n->lock);
0559     seq_printf(seq, "%-7s %s%s%s   %02x    %02d  %07ld %-8s\n",
0560            dn_addr2asc(le16_to_cpu(dn->addr), buf),
0561            (dn->flags&DN_NDFLAG_R1) ? "1" : "-",
0562            (dn->flags&DN_NDFLAG_R2) ? "2" : "-",
0563            (dn->flags&DN_NDFLAG_P3) ? "3" : "-",
0564            dn->n.nud_state,
0565            refcount_read(&dn->n.refcnt),
0566            dn->blksize,
0567            (dn->n.dev) ? dn->n.dev->name : "?");
0568     read_unlock(&n->lock);
0569 }
0570 
0571 static int dn_neigh_seq_show(struct seq_file *seq, void *v)
0572 {
0573     if (v == SEQ_START_TOKEN) {
0574         seq_puts(seq, "Addr    Flags State Use Blksize Dev\n");
0575     } else {
0576         dn_neigh_format_entry(seq, v);
0577     }
0578 
0579     return 0;
0580 }
0581 
0582 static void *dn_neigh_seq_start(struct seq_file *seq, loff_t *pos)
0583 {
0584     return neigh_seq_start(seq, pos, &dn_neigh_table,
0585                    NEIGH_SEQ_NEIGH_ONLY);
0586 }
0587 
0588 static const struct seq_operations dn_neigh_seq_ops = {
0589     .start = dn_neigh_seq_start,
0590     .next  = neigh_seq_next,
0591     .stop  = neigh_seq_stop,
0592     .show  = dn_neigh_seq_show,
0593 };
0594 #endif
0595 
0596 void __init dn_neigh_init(void)
0597 {
0598     neigh_table_init(NEIGH_DN_TABLE, &dn_neigh_table);
0599     proc_create_net("decnet_neigh", 0444, init_net.proc_net,
0600             &dn_neigh_seq_ops, sizeof(struct neigh_seq_state));
0601 }
0602 
0603 void __exit dn_neigh_cleanup(void)
0604 {
0605     remove_proc_entry("decnet_neigh", init_net.proc_net);
0606     neigh_table_clear(NEIGH_DN_TABLE, &dn_neigh_table);
0607 }