dn_neigh.c (16019B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * DECnet An implementation of the DECnet protocol suite for the LINUX 4 * operating system. DECnet is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * DECnet Neighbour Functions (Adjacency Database and 8 * On-Ethernet Cache) 9 * 10 * Author: Steve Whitehouse <SteveW@ACM.org> 11 * 12 * 13 * Changes: 14 * Steve Whitehouse : Fixed router listing routine 15 * Steve Whitehouse : Added error_report functions 16 * Steve Whitehouse : Added default router detection 17 * Steve Whitehouse : Hop counts in outgoing messages 18 * Steve Whitehouse : Fixed src/dst in outgoing messages so 19 * forwarding now stands a good chance of 20 * working. 21 * Steve Whitehouse : Fixed neighbour states (for now anyway). 22 * Steve Whitehouse : Made error_report functions dummies. This 23 * is not the right place to return skbs. 24 * Steve Whitehouse : Convert to seq_file 25 * 26 */ 27 28#include <linux/net.h> 29#include <linux/module.h> 30#include <linux/socket.h> 31#include <linux/if_arp.h> 32#include <linux/slab.h> 33#include <linux/if_ether.h> 34#include <linux/init.h> 35#include <linux/proc_fs.h> 36#include <linux/string.h> 37#include <linux/netfilter_decnet.h> 38#include <linux/spinlock.h> 39#include <linux/seq_file.h> 40#include <linux/rcupdate.h> 41#include <linux/jhash.h> 42#include <linux/atomic.h> 43#include <net/net_namespace.h> 44#include <net/neighbour.h> 45#include <net/dst.h> 46#include <net/flow.h> 47#include <net/dn.h> 48#include <net/dn_dev.h> 49#include <net/dn_neigh.h> 50#include <net/dn_route.h> 51 52static int dn_neigh_construct(struct neighbour *); 53static void dn_neigh_error_report(struct neighbour *, struct sk_buff *); 54static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb); 55 56/* 57 * Operations for adding the link layer header. 58 */ 59static const struct neigh_ops dn_neigh_ops = { 60 .family = AF_DECnet, 61 .error_report = dn_neigh_error_report, 62 .output = dn_neigh_output, 63 .connected_output = dn_neigh_output, 64}; 65 66static u32 dn_neigh_hash(const void *pkey, 67 const struct net_device *dev, 68 __u32 *hash_rnd) 69{ 70 return jhash_2words(*(__u16 *)pkey, 0, hash_rnd[0]); 71} 72 73static bool dn_key_eq(const struct neighbour *neigh, const void *pkey) 74{ 75 return neigh_key_eq16(neigh, pkey); 76} 77 78struct neigh_table dn_neigh_table = { 79 .family = PF_DECnet, 80 .entry_size = NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)), 81 .key_len = sizeof(__le16), 82 .protocol = cpu_to_be16(ETH_P_DNA_RT), 83 .hash = dn_neigh_hash, 84 .key_eq = dn_key_eq, 85 .constructor = dn_neigh_construct, 86 .id = "dn_neigh_cache", 87 .parms ={ 88 .tbl = &dn_neigh_table, 89 .reachable_time = 30 * HZ, 90 .data = { 91 [NEIGH_VAR_MCAST_PROBES] = 0, 92 [NEIGH_VAR_UCAST_PROBES] = 0, 93 [NEIGH_VAR_APP_PROBES] = 0, 94 [NEIGH_VAR_RETRANS_TIME] = 1 * HZ, 95 [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ, 96 [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ, 97 [NEIGH_VAR_GC_STALETIME] = 60 * HZ, 98 [NEIGH_VAR_QUEUE_LEN_BYTES] = SK_WMEM_MAX, 99 [NEIGH_VAR_PROXY_QLEN] = 0, 100 [NEIGH_VAR_ANYCAST_DELAY] = 0, 101 [NEIGH_VAR_PROXY_DELAY] = 0, 102 [NEIGH_VAR_LOCKTIME] = 1 * HZ, 103 }, 104 }, 105 .gc_interval = 30 * HZ, 106 .gc_thresh1 = 128, 107 .gc_thresh2 = 512, 108 .gc_thresh3 = 1024, 109}; 110 111static int dn_neigh_construct(struct neighbour *neigh) 112{ 113 struct net_device *dev = neigh->dev; 114 struct dn_neigh *dn = container_of(neigh, struct dn_neigh, n); 115 struct dn_dev *dn_db; 116 struct neigh_parms *parms; 117 118 rcu_read_lock(); 119 dn_db = rcu_dereference(dev->dn_ptr); 120 if (dn_db == NULL) { 121 rcu_read_unlock(); 122 return -EINVAL; 123 } 124 125 parms = dn_db->neigh_parms; 126 if (!parms) { 127 rcu_read_unlock(); 128 return -EINVAL; 129 } 130 131 __neigh_parms_put(neigh->parms); 132 neigh->parms = neigh_parms_clone(parms); 133 rcu_read_unlock(); 134 135 neigh->ops = &dn_neigh_ops; 136 neigh->nud_state = NUD_NOARP; 137 neigh->output = neigh->ops->connected_output; 138 139 if ((dev->type == ARPHRD_IPGRE) || (dev->flags & IFF_POINTOPOINT)) 140 memcpy(neigh->ha, dev->broadcast, dev->addr_len); 141 else if ((dev->type == ARPHRD_ETHER) || (dev->type == ARPHRD_LOOPBACK)) 142 dn_dn2eth(neigh->ha, dn->addr); 143 else { 144 net_dbg_ratelimited("Trying to create neigh for hw %d\n", 145 dev->type); 146 return -EINVAL; 147 } 148 149 /* 150 * Make an estimate of the remote block size by assuming that its 151 * two less then the device mtu, which it true for ethernet (and 152 * other things which support long format headers) since there is 153 * an extra length field (of 16 bits) which isn't part of the 154 * ethernet headers and which the DECnet specs won't admit is part 155 * of the DECnet routing headers either. 156 * 157 * If we over estimate here its no big deal, the NSP negotiations 158 * will prevent us from sending packets which are too large for the 159 * remote node to handle. In any case this figure is normally updated 160 * by a hello message in most cases. 161 */ 162 dn->blksize = dev->mtu - 2; 163 164 return 0; 165} 166 167static void dn_neigh_error_report(struct neighbour *neigh, struct sk_buff *skb) 168{ 169 printk(KERN_DEBUG "dn_neigh_error_report: called\n"); 170 kfree_skb(skb); 171} 172 173static int dn_neigh_output(struct neighbour *neigh, struct sk_buff *skb) 174{ 175 struct dst_entry *dst = skb_dst(skb); 176 struct dn_route *rt = (struct dn_route *)dst; 177 struct net_device *dev = neigh->dev; 178 char mac_addr[ETH_ALEN]; 179 unsigned int seq; 180 int err; 181 182 dn_dn2eth(mac_addr, rt->rt_local_src); 183 do { 184 seq = read_seqbegin(&neigh->ha_lock); 185 err = dev_hard_header(skb, dev, ntohs(skb->protocol), 186 neigh->ha, mac_addr, skb->len); 187 } while (read_seqretry(&neigh->ha_lock, seq)); 188 189 if (err >= 0) 190 err = dev_queue_xmit(skb); 191 else { 192 kfree_skb(skb); 193 err = -EINVAL; 194 } 195 return err; 196} 197 198static int dn_neigh_output_packet(struct net *net, struct sock *sk, struct sk_buff *skb) 199{ 200 struct dst_entry *dst = skb_dst(skb); 201 struct dn_route *rt = (struct dn_route *)dst; 202 struct neighbour *neigh = rt->n; 203 204 return neigh->output(neigh, skb); 205} 206 207/* 208 * For talking to broadcast devices: Ethernet & PPP 209 */ 210static int dn_long_output(struct neighbour *neigh, struct sock *sk, 211 struct sk_buff *skb) 212{ 213 struct net_device *dev = neigh->dev; 214 int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3; 215 unsigned char *data; 216 struct dn_long_packet *lp; 217 struct dn_skb_cb *cb = DN_SKB_CB(skb); 218 219 220 if (skb_headroom(skb) < headroom) { 221 struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); 222 if (skb2 == NULL) { 223 net_crit_ratelimited("dn_long_output: no memory\n"); 224 kfree_skb(skb); 225 return -ENOBUFS; 226 } 227 consume_skb(skb); 228 skb = skb2; 229 net_info_ratelimited("dn_long_output: Increasing headroom\n"); 230 } 231 232 data = skb_push(skb, sizeof(struct dn_long_packet) + 3); 233 lp = (struct dn_long_packet *)(data+3); 234 235 *((__le16 *)data) = cpu_to_le16(skb->len - 2); 236 *(data + 2) = 1 | DN_RT_F_PF; /* Padding */ 237 238 lp->msgflg = DN_RT_PKT_LONG|(cb->rt_flags&(DN_RT_F_IE|DN_RT_F_RQR|DN_RT_F_RTS)); 239 lp->d_area = lp->d_subarea = 0; 240 dn_dn2eth(lp->d_id, cb->dst); 241 lp->s_area = lp->s_subarea = 0; 242 dn_dn2eth(lp->s_id, cb->src); 243 lp->nl2 = 0; 244 lp->visit_ct = cb->hops & 0x3f; 245 lp->s_class = 0; 246 lp->pt = 0; 247 248 skb_reset_network_header(skb); 249 250 return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, 251 &init_net, sk, skb, NULL, neigh->dev, 252 dn_neigh_output_packet); 253} 254 255/* 256 * For talking to pointopoint and multidrop devices: DDCMP and X.25 257 */ 258static int dn_short_output(struct neighbour *neigh, struct sock *sk, 259 struct sk_buff *skb) 260{ 261 struct net_device *dev = neigh->dev; 262 int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2; 263 struct dn_short_packet *sp; 264 unsigned char *data; 265 struct dn_skb_cb *cb = DN_SKB_CB(skb); 266 267 268 if (skb_headroom(skb) < headroom) { 269 struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); 270 if (skb2 == NULL) { 271 net_crit_ratelimited("dn_short_output: no memory\n"); 272 kfree_skb(skb); 273 return -ENOBUFS; 274 } 275 consume_skb(skb); 276 skb = skb2; 277 net_info_ratelimited("dn_short_output: Increasing headroom\n"); 278 } 279 280 data = skb_push(skb, sizeof(struct dn_short_packet) + 2); 281 *((__le16 *)data) = cpu_to_le16(skb->len - 2); 282 sp = (struct dn_short_packet *)(data+2); 283 284 sp->msgflg = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS)); 285 sp->dstnode = cb->dst; 286 sp->srcnode = cb->src; 287 sp->forward = cb->hops & 0x3f; 288 289 skb_reset_network_header(skb); 290 291 return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, 292 &init_net, sk, skb, NULL, neigh->dev, 293 dn_neigh_output_packet); 294} 295 296/* 297 * For talking to DECnet phase III nodes 298 * Phase 3 output is the same as short output, execpt that 299 * it clears the area bits before transmission. 300 */ 301static int dn_phase3_output(struct neighbour *neigh, struct sock *sk, 302 struct sk_buff *skb) 303{ 304 struct net_device *dev = neigh->dev; 305 int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2; 306 struct dn_short_packet *sp; 307 unsigned char *data; 308 struct dn_skb_cb *cb = DN_SKB_CB(skb); 309 310 if (skb_headroom(skb) < headroom) { 311 struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); 312 if (skb2 == NULL) { 313 net_crit_ratelimited("dn_phase3_output: no memory\n"); 314 kfree_skb(skb); 315 return -ENOBUFS; 316 } 317 consume_skb(skb); 318 skb = skb2; 319 net_info_ratelimited("dn_phase3_output: Increasing headroom\n"); 320 } 321 322 data = skb_push(skb, sizeof(struct dn_short_packet) + 2); 323 *((__le16 *)data) = cpu_to_le16(skb->len - 2); 324 sp = (struct dn_short_packet *)(data + 2); 325 326 sp->msgflg = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS)); 327 sp->dstnode = cb->dst & cpu_to_le16(0x03ff); 328 sp->srcnode = cb->src & cpu_to_le16(0x03ff); 329 sp->forward = cb->hops & 0x3f; 330 331 skb_reset_network_header(skb); 332 333 return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, 334 &init_net, sk, skb, NULL, neigh->dev, 335 dn_neigh_output_packet); 336} 337 338int dn_to_neigh_output(struct net *net, struct sock *sk, struct sk_buff *skb) 339{ 340 struct dst_entry *dst = skb_dst(skb); 341 struct dn_route *rt = (struct dn_route *) dst; 342 struct neighbour *neigh = rt->n; 343 struct dn_neigh *dn = container_of(neigh, struct dn_neigh, n); 344 struct dn_dev *dn_db; 345 bool use_long; 346 347 rcu_read_lock(); 348 dn_db = rcu_dereference(neigh->dev->dn_ptr); 349 if (dn_db == NULL) { 350 rcu_read_unlock(); 351 return -EINVAL; 352 } 353 use_long = dn_db->use_long; 354 rcu_read_unlock(); 355 356 if (dn->flags & DN_NDFLAG_P3) 357 return dn_phase3_output(neigh, sk, skb); 358 if (use_long) 359 return dn_long_output(neigh, sk, skb); 360 else 361 return dn_short_output(neigh, sk, skb); 362} 363 364/* 365 * Unfortunately, the neighbour code uses the device in its hash 366 * function, so we don't get any advantage from it. This function 367 * basically does a neigh_lookup(), but without comparing the device 368 * field. This is required for the On-Ethernet cache 369 */ 370 371/* 372 * Pointopoint link receives a hello message 373 */ 374void dn_neigh_pointopoint_hello(struct sk_buff *skb) 375{ 376 kfree_skb(skb); 377} 378 379/* 380 * Ethernet router hello message received 381 */ 382int dn_neigh_router_hello(struct net *net, struct sock *sk, struct sk_buff *skb) 383{ 384 struct rtnode_hello_message *msg = (struct rtnode_hello_message *)skb->data; 385 386 struct neighbour *neigh; 387 struct dn_neigh *dn; 388 struct dn_dev *dn_db; 389 __le16 src; 390 391 src = dn_eth2dn(msg->id); 392 393 neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1); 394 395 dn = container_of(neigh, struct dn_neigh, n); 396 397 if (neigh) { 398 write_lock(&neigh->lock); 399 400 neigh->used = jiffies; 401 dn_db = rcu_dereference(neigh->dev->dn_ptr); 402 403 if (!(neigh->nud_state & NUD_PERMANENT)) { 404 neigh->updated = jiffies; 405 406 if (neigh->dev->type == ARPHRD_ETHER) 407 memcpy(neigh->ha, ð_hdr(skb)->h_source, ETH_ALEN); 408 409 dn->blksize = le16_to_cpu(msg->blksize); 410 dn->priority = msg->priority; 411 412 dn->flags &= ~DN_NDFLAG_P3; 413 414 switch (msg->iinfo & DN_RT_INFO_TYPE) { 415 case DN_RT_INFO_L1RT: 416 dn->flags &=~DN_NDFLAG_R2; 417 dn->flags |= DN_NDFLAG_R1; 418 break; 419 case DN_RT_INFO_L2RT: 420 dn->flags |= DN_NDFLAG_R2; 421 } 422 } 423 424 /* Only use routers in our area */ 425 if ((le16_to_cpu(src)>>10) == (le16_to_cpu((decnet_address))>>10)) { 426 if (!dn_db->router) { 427 dn_db->router = neigh_clone(neigh); 428 } else { 429 if (msg->priority > container_of(dn_db->router, 430 struct dn_neigh, n)->priority) 431 neigh_release(xchg(&dn_db->router, neigh_clone(neigh))); 432 } 433 } 434 write_unlock(&neigh->lock); 435 neigh_release(neigh); 436 } 437 438 kfree_skb(skb); 439 return 0; 440} 441 442/* 443 * Endnode hello message received 444 */ 445int dn_neigh_endnode_hello(struct net *net, struct sock *sk, struct sk_buff *skb) 446{ 447 struct endnode_hello_message *msg = (struct endnode_hello_message *)skb->data; 448 struct neighbour *neigh; 449 struct dn_neigh *dn; 450 __le16 src; 451 452 src = dn_eth2dn(msg->id); 453 454 neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1); 455 456 dn = container_of(neigh, struct dn_neigh, n); 457 458 if (neigh) { 459 write_lock(&neigh->lock); 460 461 neigh->used = jiffies; 462 463 if (!(neigh->nud_state & NUD_PERMANENT)) { 464 neigh->updated = jiffies; 465 466 if (neigh->dev->type == ARPHRD_ETHER) 467 memcpy(neigh->ha, ð_hdr(skb)->h_source, ETH_ALEN); 468 dn->flags &= ~(DN_NDFLAG_R1 | DN_NDFLAG_R2); 469 dn->blksize = le16_to_cpu(msg->blksize); 470 dn->priority = 0; 471 } 472 473 write_unlock(&neigh->lock); 474 neigh_release(neigh); 475 } 476 477 kfree_skb(skb); 478 return 0; 479} 480 481static char *dn_find_slot(char *base, int max, int priority) 482{ 483 int i; 484 unsigned char *min = NULL; 485 486 base += 6; /* skip first id */ 487 488 for(i = 0; i < max; i++) { 489 if (!min || (*base < *min)) 490 min = base; 491 base += 7; /* find next priority */ 492 } 493 494 if (!min) 495 return NULL; 496 497 return (*min < priority) ? (min - 6) : NULL; 498} 499 500struct elist_cb_state { 501 struct net_device *dev; 502 unsigned char *ptr; 503 unsigned char *rs; 504 int t, n; 505}; 506 507static void neigh_elist_cb(struct neighbour *neigh, void *_info) 508{ 509 struct elist_cb_state *s = _info; 510 struct dn_neigh *dn; 511 512 if (neigh->dev != s->dev) 513 return; 514 515 dn = container_of(neigh, struct dn_neigh, n); 516 if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2))) 517 return; 518 519 if (s->t == s->n) 520 s->rs = dn_find_slot(s->ptr, s->n, dn->priority); 521 else 522 s->t++; 523 if (s->rs == NULL) 524 return; 525 526 dn_dn2eth(s->rs, dn->addr); 527 s->rs += 6; 528 *(s->rs) = neigh->nud_state & NUD_CONNECTED ? 0x80 : 0x0; 529 *(s->rs) |= dn->priority; 530 s->rs++; 531} 532 533int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n) 534{ 535 struct elist_cb_state state; 536 537 state.dev = dev; 538 state.t = 0; 539 state.n = n; 540 state.ptr = ptr; 541 state.rs = ptr; 542 543 neigh_for_each(&dn_neigh_table, neigh_elist_cb, &state); 544 545 return state.t; 546} 547 548 549#ifdef CONFIG_PROC_FS 550 551static inline void dn_neigh_format_entry(struct seq_file *seq, 552 struct neighbour *n) 553{ 554 struct dn_neigh *dn = container_of(n, struct dn_neigh, n); 555 char buf[DN_ASCBUF_LEN]; 556 557 read_lock(&n->lock); 558 seq_printf(seq, "%-7s %s%s%s %02x %02d %07ld %-8s\n", 559 dn_addr2asc(le16_to_cpu(dn->addr), buf), 560 (dn->flags&DN_NDFLAG_R1) ? "1" : "-", 561 (dn->flags&DN_NDFLAG_R2) ? "2" : "-", 562 (dn->flags&DN_NDFLAG_P3) ? "3" : "-", 563 dn->n.nud_state, 564 refcount_read(&dn->n.refcnt), 565 dn->blksize, 566 (dn->n.dev) ? dn->n.dev->name : "?"); 567 read_unlock(&n->lock); 568} 569 570static int dn_neigh_seq_show(struct seq_file *seq, void *v) 571{ 572 if (v == SEQ_START_TOKEN) { 573 seq_puts(seq, "Addr Flags State Use Blksize Dev\n"); 574 } else { 575 dn_neigh_format_entry(seq, v); 576 } 577 578 return 0; 579} 580 581static void *dn_neigh_seq_start(struct seq_file *seq, loff_t *pos) 582{ 583 return neigh_seq_start(seq, pos, &dn_neigh_table, 584 NEIGH_SEQ_NEIGH_ONLY); 585} 586 587static const struct seq_operations dn_neigh_seq_ops = { 588 .start = dn_neigh_seq_start, 589 .next = neigh_seq_next, 590 .stop = neigh_seq_stop, 591 .show = dn_neigh_seq_show, 592}; 593#endif 594 595void __init dn_neigh_init(void) 596{ 597 neigh_table_init(NEIGH_DN_TABLE, &dn_neigh_table); 598 proc_create_net("decnet_neigh", 0444, init_net.proc_net, 599 &dn_neigh_seq_ops, sizeof(struct neigh_seq_state)); 600} 601 602void __exit dn_neigh_cleanup(void) 603{ 604 remove_proc_entry("decnet_neigh", init_net.proc_net); 605 neigh_table_clear(NEIGH_DN_TABLE, &dn_neigh_table); 606}