route.c (320424c7d44f54c18df9812fd7c45f6963524002) | route.c (6126891c6d4f6f4ef50323d2020635ee255a796e) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Linux INET6 implementation 4 * FIB front-end. 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 */ --- 2312 unchanged lines hidden (view full) --- 2321 } else { 2322 keys->addrs.v6addrs.src = key_iph->saddr; 2323 keys->addrs.v6addrs.dst = key_iph->daddr; 2324 keys->tags.flow_label = ip6_flowlabel(key_iph); 2325 keys->basic.ip_proto = key_iph->nexthdr; 2326 } 2327} 2328 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Linux INET6 implementation 4 * FIB front-end. 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 */ --- 2312 unchanged lines hidden (view full) --- 2321 } else { 2322 keys->addrs.v6addrs.src = key_iph->saddr; 2323 keys->addrs.v6addrs.dst = key_iph->daddr; 2324 keys->tags.flow_label = ip6_flowlabel(key_iph); 2325 keys->basic.ip_proto = key_iph->nexthdr; 2326 } 2327} 2328 |
2329static u32 rt6_multipath_custom_hash_outer(const struct net *net, 2330 const struct sk_buff *skb, 2331 bool *p_has_inner) 2332{ 2333 u32 hash_fields = ip6_multipath_hash_fields(net); 2334 struct flow_keys keys, hash_keys; 2335 2336 if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_OUTER_MASK)) 2337 return 0; 2338 2339 memset(&hash_keys, 0, sizeof(hash_keys)); 2340 skb_flow_dissect_flow_keys(skb, &keys, FLOW_DISSECTOR_F_STOP_AT_ENCAP); 2341 2342 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2343 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_SRC_IP) 2344 hash_keys.addrs.v6addrs.src = keys.addrs.v6addrs.src; 2345 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_DST_IP) 2346 hash_keys.addrs.v6addrs.dst = keys.addrs.v6addrs.dst; 2347 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_IP_PROTO) 2348 hash_keys.basic.ip_proto = keys.basic.ip_proto; 2349 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_FLOWLABEL) 2350 hash_keys.tags.flow_label = keys.tags.flow_label; 2351 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_SRC_PORT) 2352 hash_keys.ports.src = keys.ports.src; 2353 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_DST_PORT) 2354 hash_keys.ports.dst = keys.ports.dst; 2355 2356 *p_has_inner = !!(keys.control.flags & FLOW_DIS_ENCAPSULATION); 2357 return flow_hash_from_keys(&hash_keys); 2358} 2359 2360static u32 rt6_multipath_custom_hash_inner(const struct net *net, 2361 const struct sk_buff *skb, 2362 bool has_inner) 2363{ 2364 u32 hash_fields = ip6_multipath_hash_fields(net); 2365 struct flow_keys keys, hash_keys; 2366 2367 /* We assume the packet carries an encapsulation, but if none was 2368 * encountered during dissection of the outer flow, then there is no 2369 * point in calling the flow dissector again. 2370 */ 2371 if (!has_inner) 2372 return 0; 2373 2374 if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_MASK)) 2375 return 0; 2376 2377 memset(&hash_keys, 0, sizeof(hash_keys)); 2378 skb_flow_dissect_flow_keys(skb, &keys, 0); 2379 2380 if (!(keys.control.flags & FLOW_DIS_ENCAPSULATION)) 2381 return 0; 2382 2383 if (keys.control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { 2384 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS; 2385 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_SRC_IP) 2386 hash_keys.addrs.v4addrs.src = keys.addrs.v4addrs.src; 2387 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_DST_IP) 2388 hash_keys.addrs.v4addrs.dst = keys.addrs.v4addrs.dst; 2389 } else if (keys.control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { 2390 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2391 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_SRC_IP) 2392 hash_keys.addrs.v6addrs.src = keys.addrs.v6addrs.src; 2393 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_DST_IP) 2394 hash_keys.addrs.v6addrs.dst = keys.addrs.v6addrs.dst; 2395 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_FLOWLABEL) 2396 hash_keys.tags.flow_label = keys.tags.flow_label; 2397 } 2398 2399 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_IP_PROTO) 2400 hash_keys.basic.ip_proto = keys.basic.ip_proto; 2401 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_SRC_PORT) 2402 hash_keys.ports.src = keys.ports.src; 2403 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_INNER_DST_PORT) 2404 hash_keys.ports.dst = keys.ports.dst; 2405 2406 return flow_hash_from_keys(&hash_keys); 2407} 2408 2409static u32 rt6_multipath_custom_hash_skb(const struct net *net, 2410 const struct sk_buff *skb) 2411{ 2412 u32 mhash, mhash_inner; 2413 bool has_inner = true; 2414 2415 mhash = rt6_multipath_custom_hash_outer(net, skb, &has_inner); 2416 mhash_inner = rt6_multipath_custom_hash_inner(net, skb, has_inner); 2417 2418 return jhash_2words(mhash, mhash_inner, 0); 2419} 2420 2421static u32 rt6_multipath_custom_hash_fl6(const struct net *net, 2422 const struct flowi6 *fl6) 2423{ 2424 u32 hash_fields = ip6_multipath_hash_fields(net); 2425 struct flow_keys hash_keys; 2426 2427 if (!(hash_fields & FIB_MULTIPATH_HASH_FIELD_OUTER_MASK)) 2428 return 0; 2429 2430 memset(&hash_keys, 0, sizeof(hash_keys)); 2431 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2432 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_SRC_IP) 2433 hash_keys.addrs.v6addrs.src = fl6->saddr; 2434 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_DST_IP) 2435 hash_keys.addrs.v6addrs.dst = fl6->daddr; 2436 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_IP_PROTO) 2437 hash_keys.basic.ip_proto = fl6->flowi6_proto; 2438 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_FLOWLABEL) 2439 hash_keys.tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6); 2440 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_SRC_PORT) 2441 hash_keys.ports.src = fl6->fl6_sport; 2442 if (hash_fields & FIB_MULTIPATH_HASH_FIELD_DST_PORT) 2443 hash_keys.ports.dst = fl6->fl6_dport; 2444 2445 return flow_hash_from_keys(&hash_keys); 2446} 2447 |
|
2329/* if skb is set it will be used and fl6 can be NULL */ 2330u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6, 2331 const struct sk_buff *skb, struct flow_keys *flkeys) 2332{ 2333 struct flow_keys hash_keys; | 2448/* if skb is set it will be used and fl6 can be NULL */ 2449u32 rt6_multipath_hash(const struct net *net, const struct flowi6 *fl6, 2450 const struct sk_buff *skb, struct flow_keys *flkeys) 2451{ 2452 struct flow_keys hash_keys; |
2334 u32 mhash; | 2453 u32 mhash = 0; |
2335 2336 switch (ip6_multipath_hash_policy(net)) { 2337 case 0: 2338 memset(&hash_keys, 0, sizeof(hash_keys)); 2339 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2340 if (skb) { 2341 ip6_multipath_l3_keys(skb, &hash_keys, flkeys); 2342 } else { 2343 hash_keys.addrs.v6addrs.src = fl6->saddr; 2344 hash_keys.addrs.v6addrs.dst = fl6->daddr; 2345 hash_keys.tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6); 2346 hash_keys.basic.ip_proto = fl6->flowi6_proto; 2347 } | 2454 2455 switch (ip6_multipath_hash_policy(net)) { 2456 case 0: 2457 memset(&hash_keys, 0, sizeof(hash_keys)); 2458 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2459 if (skb) { 2460 ip6_multipath_l3_keys(skb, &hash_keys, flkeys); 2461 } else { 2462 hash_keys.addrs.v6addrs.src = fl6->saddr; 2463 hash_keys.addrs.v6addrs.dst = fl6->daddr; 2464 hash_keys.tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6); 2465 hash_keys.basic.ip_proto = fl6->flowi6_proto; 2466 } |
2467 mhash = flow_hash_from_keys(&hash_keys); |
|
2348 break; 2349 case 1: 2350 if (skb) { 2351 unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP; 2352 struct flow_keys keys; 2353 2354 /* short-circuit if we already have L4 hash present */ 2355 if (skb->l4_hash) --- 15 unchanged lines hidden (view full) --- 2371 memset(&hash_keys, 0, sizeof(hash_keys)); 2372 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2373 hash_keys.addrs.v6addrs.src = fl6->saddr; 2374 hash_keys.addrs.v6addrs.dst = fl6->daddr; 2375 hash_keys.ports.src = fl6->fl6_sport; 2376 hash_keys.ports.dst = fl6->fl6_dport; 2377 hash_keys.basic.ip_proto = fl6->flowi6_proto; 2378 } | 2468 break; 2469 case 1: 2470 if (skb) { 2471 unsigned int flag = FLOW_DISSECTOR_F_STOP_AT_ENCAP; 2472 struct flow_keys keys; 2473 2474 /* short-circuit if we already have L4 hash present */ 2475 if (skb->l4_hash) --- 15 unchanged lines hidden (view full) --- 2491 memset(&hash_keys, 0, sizeof(hash_keys)); 2492 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2493 hash_keys.addrs.v6addrs.src = fl6->saddr; 2494 hash_keys.addrs.v6addrs.dst = fl6->daddr; 2495 hash_keys.ports.src = fl6->fl6_sport; 2496 hash_keys.ports.dst = fl6->fl6_dport; 2497 hash_keys.basic.ip_proto = fl6->flowi6_proto; 2498 } |
2499 mhash = flow_hash_from_keys(&hash_keys); |
|
2379 break; 2380 case 2: 2381 memset(&hash_keys, 0, sizeof(hash_keys)); 2382 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2383 if (skb) { 2384 struct flow_keys keys; 2385 2386 if (!flkeys) { --- 20 unchanged lines hidden (view full) --- 2407 } else { 2408 /* Same as case 0 */ 2409 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2410 hash_keys.addrs.v6addrs.src = fl6->saddr; 2411 hash_keys.addrs.v6addrs.dst = fl6->daddr; 2412 hash_keys.tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6); 2413 hash_keys.basic.ip_proto = fl6->flowi6_proto; 2414 } | 2500 break; 2501 case 2: 2502 memset(&hash_keys, 0, sizeof(hash_keys)); 2503 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2504 if (skb) { 2505 struct flow_keys keys; 2506 2507 if (!flkeys) { --- 20 unchanged lines hidden (view full) --- 2528 } else { 2529 /* Same as case 0 */ 2530 hash_keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS; 2531 hash_keys.addrs.v6addrs.src = fl6->saddr; 2532 hash_keys.addrs.v6addrs.dst = fl6->daddr; 2533 hash_keys.tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6); 2534 hash_keys.basic.ip_proto = fl6->flowi6_proto; 2535 } |
2536 mhash = flow_hash_from_keys(&hash_keys); |
|
2415 break; | 2537 break; |
2538 case 3: 2539 if (skb) 2540 mhash = rt6_multipath_custom_hash_skb(net, skb); 2541 else 2542 mhash = rt6_multipath_custom_hash_fl6(net, fl6); 2543 break; |
|
2416 } | 2544 } |
2417 mhash = flow_hash_from_keys(&hash_keys); | |
2418 2419 return mhash >> 1; 2420} 2421 2422/* Called with rcu held */ 2423void ip6_route_input(struct sk_buff *skb) 2424{ 2425 const struct ipv6hdr *iph = ipv6_hdr(skb); --- 4080 unchanged lines hidden (view full) --- 6506int __init ip6_route_init(void) 6507{ 6508 int ret; 6509 int cpu; 6510 6511 ret = -ENOMEM; 6512 ip6_dst_ops_template.kmem_cachep = 6513 kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, | 2545 2546 return mhash >> 1; 2547} 2548 2549/* Called with rcu held */ 2550void ip6_route_input(struct sk_buff *skb) 2551{ 2552 const struct ipv6hdr *iph = ipv6_hdr(skb); --- 4080 unchanged lines hidden (view full) --- 6633int __init ip6_route_init(void) 6634{ 6635 int ret; 6636 int cpu; 6637 6638 ret = -ENOMEM; 6639 ip6_dst_ops_template.kmem_cachep = 6640 kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0, |
6514 SLAB_HWCACHE_ALIGN, NULL); | 6641 SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT, NULL); |
6515 if (!ip6_dst_ops_template.kmem_cachep) 6516 goto out; 6517 6518 ret = dst_entries_init(&ip6_dst_blackhole_ops); 6519 if (ret) 6520 goto out_kmem_cache; 6521 6522 ret = register_pernet_subsys(&ipv6_inetpeer_ops); --- 100 unchanged lines hidden --- | 6642 if (!ip6_dst_ops_template.kmem_cachep) 6643 goto out; 6644 6645 ret = dst_entries_init(&ip6_dst_blackhole_ops); 6646 if (ret) 6647 goto out_kmem_cache; 6648 6649 ret = register_pernet_subsys(&ipv6_inetpeer_ops); --- 100 unchanged lines hidden --- |