diff options
| author | Thomas Graf <tgraf@suug.ch> | 2005-06-08 18:10:48 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2005-06-08 18:10:48 -0400 |
| commit | 4890062960cbc4d3cebdbd8261a68bc85efcf5d4 (patch) | |
| tree | c834cb84fc939d64d5331a769abe6c20b8347ac8 | |
| parent | b824979aeccbfd997e6e5dbe75c47d586b5a2923 (diff) | |
[PKT_SCHED]: Allow socket attributes to be matched on via meta ematch
Adds meta collectors for all socket attributes that make sense
to be filtered upon. Some of them are only useful for debugging
but having them doesn't hurt.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/tc_ematch/tc_em_meta.h | 30 | ||||
| -rw-r--r-- | net/sched/em_meta.c | 291 |
2 files changed, 297 insertions, 24 deletions
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index aa6b48bb4dcd..a6b2cc530af5 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h | |||
| @@ -56,6 +56,36 @@ enum | |||
| 56 | TCF_META_ID_TCCLASSID, | 56 | TCF_META_ID_TCCLASSID, |
| 57 | TCF_META_ID_RTCLASSID, | 57 | TCF_META_ID_RTCLASSID, |
| 58 | TCF_META_ID_RTIIF, | 58 | TCF_META_ID_RTIIF, |
| 59 | TCF_META_ID_SK_FAMILY, | ||
| 60 | TCF_META_ID_SK_STATE, | ||
| 61 | TCF_META_ID_SK_REUSE, | ||
| 62 | TCF_META_ID_SK_BOUND_IF, | ||
| 63 | TCF_META_ID_SK_REFCNT, | ||
| 64 | TCF_META_ID_SK_SHUTDOWN, | ||
| 65 | TCF_META_ID_SK_PROTO, | ||
| 66 | TCF_META_ID_SK_TYPE, | ||
| 67 | TCF_META_ID_SK_RCVBUF, | ||
| 68 | TCF_META_ID_SK_RMEM_ALLOC, | ||
| 69 | TCF_META_ID_SK_WMEM_ALLOC, | ||
| 70 | TCF_META_ID_SK_OMEM_ALLOC, | ||
| 71 | TCF_META_ID_SK_WMEM_QUEUED, | ||
| 72 | TCF_META_ID_SK_RCV_QLEN, | ||
| 73 | TCF_META_ID_SK_SND_QLEN, | ||
| 74 | TCF_META_ID_SK_ERR_QLEN, | ||
| 75 | TCF_META_ID_SK_FORWARD_ALLOCS, | ||
| 76 | TCF_META_ID_SK_SNDBUF, | ||
| 77 | TCF_META_ID_SK_ALLOCS, | ||
| 78 | TCF_META_ID_SK_ROUTE_CAPS, | ||
| 79 | TCF_META_ID_SK_HASHENT, | ||
| 80 | TCF_META_ID_SK_LINGERTIME, | ||
| 81 | TCF_META_ID_SK_ACK_BACKLOG, | ||
| 82 | TCF_META_ID_SK_MAX_ACK_BACKLOG, | ||
| 83 | TCF_META_ID_SK_PRIO, | ||
| 84 | TCF_META_ID_SK_RCVLOWAT, | ||
| 85 | TCF_META_ID_SK_RCVTIMEO, | ||
| 86 | TCF_META_ID_SK_SNDTIMEO, | ||
| 87 | TCF_META_ID_SK_SENDMSG_OFF, | ||
| 88 | TCF_META_ID_SK_WRITE_PENDING, | ||
| 59 | __TCF_META_ID_MAX | 89 | __TCF_META_ID_MAX |
| 60 | }; | 90 | }; |
| 61 | #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) | 91 | #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) |
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index f1eeaf65cee5..ed2a46cbb67f 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | * +-----------+ +-----------+ | 32 | * +-----------+ +-----------+ |
| 33 | * | | | 33 | * | | |
| 34 | * ---> meta_ops[INT][INDEV](...) | | 34 | * ---> meta_ops[INT][INDEV](...) | |
| 35 | * | | | 35 | * | | |
| 36 | * ----------- | | 36 | * ----------- | |
| 37 | * V V | 37 | * V V |
| 38 | * +-----------+ +-----------+ | 38 | * +-----------+ +-----------+ |
| @@ -70,6 +70,7 @@ | |||
| 70 | #include <net/dst.h> | 70 | #include <net/dst.h> |
| 71 | #include <net/route.h> | 71 | #include <net/route.h> |
| 72 | #include <net/pkt_cls.h> | 72 | #include <net/pkt_cls.h> |
| 73 | #include <net/sock.h> | ||
| 73 | 74 | ||
| 74 | struct meta_obj | 75 | struct meta_obj |
| 75 | { | 76 | { |
| @@ -284,6 +285,214 @@ META_COLLECTOR(int_rtiif) | |||
| 284 | } | 285 | } |
| 285 | 286 | ||
| 286 | /************************************************************************** | 287 | /************************************************************************** |
| 288 | * Socket Attributes | ||
| 289 | **************************************************************************/ | ||
| 290 | |||
| 291 | #define SKIP_NONLOCAL(skb) \ | ||
| 292 | if (unlikely(skb->sk == NULL)) { \ | ||
| 293 | *err = -1; \ | ||
| 294 | return; \ | ||
| 295 | } | ||
| 296 | |||
| 297 | META_COLLECTOR(int_sk_family) | ||
| 298 | { | ||
| 299 | SKIP_NONLOCAL(skb); | ||
| 300 | dst->value = skb->sk->sk_family; | ||
| 301 | } | ||
| 302 | |||
| 303 | META_COLLECTOR(int_sk_state) | ||
| 304 | { | ||
| 305 | SKIP_NONLOCAL(skb); | ||
| 306 | dst->value = skb->sk->sk_state; | ||
| 307 | } | ||
| 308 | |||
| 309 | META_COLLECTOR(int_sk_reuse) | ||
| 310 | { | ||
| 311 | SKIP_NONLOCAL(skb); | ||
| 312 | dst->value = skb->sk->sk_reuse; | ||
| 313 | } | ||
| 314 | |||
| 315 | META_COLLECTOR(int_sk_bound_if) | ||
| 316 | { | ||
| 317 | SKIP_NONLOCAL(skb); | ||
| 318 | /* No error if bound_dev_if is 0, legal userspace check */ | ||
| 319 | dst->value = skb->sk->sk_bound_dev_if; | ||
| 320 | } | ||
| 321 | |||
| 322 | META_COLLECTOR(var_sk_bound_if) | ||
| 323 | { | ||
| 324 | SKIP_NONLOCAL(skb); | ||
| 325 | |||
| 326 | if (skb->sk->sk_bound_dev_if == 0) { | ||
| 327 | dst->value = (unsigned long) "any"; | ||
| 328 | dst->len = 3; | ||
| 329 | } else { | ||
| 330 | struct net_device *dev; | ||
| 331 | |||
| 332 | dev = dev_get_by_index(skb->sk->sk_bound_dev_if); | ||
| 333 | *err = var_dev(dev, dst); | ||
| 334 | if (dev) | ||
| 335 | dev_put(dev); | ||
| 336 | } | ||
| 337 | } | ||
| 338 | |||
| 339 | META_COLLECTOR(int_sk_refcnt) | ||
| 340 | { | ||
| 341 | SKIP_NONLOCAL(skb); | ||
| 342 | dst->value = atomic_read(&skb->sk->sk_refcnt); | ||
| 343 | } | ||
| 344 | |||
| 345 | META_COLLECTOR(int_sk_rcvbuf) | ||
| 346 | { | ||
| 347 | SKIP_NONLOCAL(skb); | ||
| 348 | dst->value = skb->sk->sk_rcvbuf; | ||
| 349 | } | ||
| 350 | |||
| 351 | META_COLLECTOR(int_sk_shutdown) | ||
| 352 | { | ||
| 353 | SKIP_NONLOCAL(skb); | ||
| 354 | dst->value = skb->sk->sk_shutdown; | ||
| 355 | } | ||
| 356 | |||
| 357 | META_COLLECTOR(int_sk_proto) | ||
| 358 | { | ||
| 359 | SKIP_NONLOCAL(skb); | ||
| 360 | dst->value = skb->sk->sk_protocol; | ||
| 361 | } | ||
| 362 | |||
| 363 | META_COLLECTOR(int_sk_type) | ||
| 364 | { | ||
| 365 | SKIP_NONLOCAL(skb); | ||
| 366 | dst->value = skb->sk->sk_type; | ||
| 367 | } | ||
| 368 | |||
| 369 | META_COLLECTOR(int_sk_rmem_alloc) | ||
| 370 | { | ||
| 371 | SKIP_NONLOCAL(skb); | ||
| 372 | dst->value = atomic_read(&skb->sk->sk_rmem_alloc); | ||
| 373 | } | ||
| 374 | |||
| 375 | META_COLLECTOR(int_sk_wmem_alloc) | ||
| 376 | { | ||
| 377 | SKIP_NONLOCAL(skb); | ||
| 378 | dst->value = atomic_read(&skb->sk->sk_wmem_alloc); | ||
| 379 | } | ||
| 380 | |||
| 381 | META_COLLECTOR(int_sk_omem_alloc) | ||
| 382 | { | ||
| 383 | SKIP_NONLOCAL(skb); | ||
| 384 | dst->value = atomic_read(&skb->sk->sk_omem_alloc); | ||
| 385 | } | ||
| 386 | |||
| 387 | META_COLLECTOR(int_sk_rcv_qlen) | ||
| 388 | { | ||
| 389 | SKIP_NONLOCAL(skb); | ||
| 390 | dst->value = skb->sk->sk_receive_queue.qlen; | ||
| 391 | } | ||
| 392 | |||
| 393 | META_COLLECTOR(int_sk_snd_qlen) | ||
| 394 | { | ||
| 395 | SKIP_NONLOCAL(skb); | ||
| 396 | dst->value = skb->sk->sk_write_queue.qlen; | ||
| 397 | } | ||
| 398 | |||
| 399 | META_COLLECTOR(int_sk_wmem_queued) | ||
| 400 | { | ||
| 401 | SKIP_NONLOCAL(skb); | ||
| 402 | dst->value = skb->sk->sk_wmem_queued; | ||
| 403 | } | ||
| 404 | |||
| 405 | META_COLLECTOR(int_sk_fwd_alloc) | ||
| 406 | { | ||
| 407 | SKIP_NONLOCAL(skb); | ||
| 408 | dst->value = skb->sk->sk_forward_alloc; | ||
| 409 | } | ||
| 410 | |||
| 411 | META_COLLECTOR(int_sk_sndbuf) | ||
| 412 | { | ||
| 413 | SKIP_NONLOCAL(skb); | ||
| 414 | dst->value = skb->sk->sk_sndbuf; | ||
| 415 | } | ||
| 416 | |||
| 417 | META_COLLECTOR(int_sk_alloc) | ||
| 418 | { | ||
| 419 | SKIP_NONLOCAL(skb); | ||
| 420 | dst->value = skb->sk->sk_allocation; | ||
| 421 | } | ||
| 422 | |||
| 423 | META_COLLECTOR(int_sk_route_caps) | ||
| 424 | { | ||
| 425 | SKIP_NONLOCAL(skb); | ||
| 426 | dst->value = skb->sk->sk_route_caps; | ||
| 427 | } | ||
| 428 | |||
| 429 | META_COLLECTOR(int_sk_hashent) | ||
| 430 | { | ||
| 431 | SKIP_NONLOCAL(skb); | ||
| 432 | dst->value = skb->sk->sk_hashent; | ||
| 433 | } | ||
| 434 | |||
| 435 | META_COLLECTOR(int_sk_lingertime) | ||
| 436 | { | ||
| 437 | SKIP_NONLOCAL(skb); | ||
| 438 | dst->value = skb->sk->sk_lingertime / HZ; | ||
| 439 | } | ||
| 440 | |||
| 441 | META_COLLECTOR(int_sk_err_qlen) | ||
| 442 | { | ||
| 443 | SKIP_NONLOCAL(skb); | ||
| 444 | dst->value = skb->sk->sk_error_queue.qlen; | ||
| 445 | } | ||
| 446 | |||
| 447 | META_COLLECTOR(int_sk_ack_bl) | ||
| 448 | { | ||
| 449 | SKIP_NONLOCAL(skb); | ||
| 450 | dst->value = skb->sk->sk_ack_backlog; | ||
| 451 | } | ||
| 452 | |||
| 453 | META_COLLECTOR(int_sk_max_ack_bl) | ||
| 454 | { | ||
| 455 | SKIP_NONLOCAL(skb); | ||
| 456 | dst->value = skb->sk->sk_max_ack_backlog; | ||
| 457 | } | ||
| 458 | |||
| 459 | META_COLLECTOR(int_sk_prio) | ||
| 460 | { | ||
| 461 | SKIP_NONLOCAL(skb); | ||
| 462 | dst->value = skb->sk->sk_priority; | ||
| 463 | } | ||
| 464 | |||
| 465 | META_COLLECTOR(int_sk_rcvlowat) | ||
| 466 | { | ||
| 467 | SKIP_NONLOCAL(skb); | ||
| 468 | dst->value = skb->sk->sk_rcvlowat; | ||
| 469 | } | ||
| 470 | |||
| 471 | META_COLLECTOR(int_sk_rcvtimeo) | ||
| 472 | { | ||
| 473 | SKIP_NONLOCAL(skb); | ||
| 474 | dst->value = skb->sk->sk_rcvtimeo / HZ; | ||
| 475 | } | ||
| 476 | |||
| 477 | META_COLLECTOR(int_sk_sndtimeo) | ||
| 478 | { | ||
| 479 | SKIP_NONLOCAL(skb); | ||
| 480 | dst->value = skb->sk->sk_sndtimeo / HZ; | ||
| 481 | } | ||
| 482 | |||
| 483 | META_COLLECTOR(int_sk_sendmsg_off) | ||
| 484 | { | ||
| 485 | SKIP_NONLOCAL(skb); | ||
| 486 | dst->value = skb->sk->sk_sndmsg_off; | ||
| 487 | } | ||
| 488 | |||
| 489 | META_COLLECTOR(int_sk_write_pend) | ||
| 490 | { | ||
| 491 | SKIP_NONLOCAL(skb); | ||
| 492 | dst->value = skb->sk->sk_write_pending; | ||
| 493 | } | ||
| 494 | |||
| 495 | /************************************************************************** | ||
| 287 | * Meta value collectors assignment table | 496 | * Meta value collectors assignment table |
| 288 | **************************************************************************/ | 497 | **************************************************************************/ |
| 289 | 498 | ||
| @@ -293,41 +502,75 @@ struct meta_ops | |||
| 293 | struct meta_value *, struct meta_obj *, int *); | 502 | struct meta_value *, struct meta_obj *, int *); |
| 294 | }; | 503 | }; |
| 295 | 504 | ||
| 505 | #define META_ID(name) TCF_META_ID_##name | ||
| 506 | #define META_FUNC(name) { .get = meta_##name } | ||
| 507 | |||
| 296 | /* Meta value operations table listing all meta value collectors and | 508 | /* Meta value operations table listing all meta value collectors and |
| 297 | * assigns them to a type and meta id. */ | 509 | * assigns them to a type and meta id. */ |
| 298 | static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { | 510 | static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { |
| 299 | [TCF_META_TYPE_VAR] = { | 511 | [TCF_META_TYPE_VAR] = { |
| 300 | [TCF_META_ID_DEV] = { .get = meta_var_dev }, | 512 | [META_ID(DEV)] = META_FUNC(var_dev), |
| 301 | [TCF_META_ID_INDEV] = { .get = meta_var_indev }, | 513 | [META_ID(INDEV)] = META_FUNC(var_indev), |
| 302 | [TCF_META_ID_REALDEV] = { .get = meta_var_realdev } | 514 | [META_ID(REALDEV)] = META_FUNC(var_realdev), |
| 515 | [META_ID(SK_BOUND_IF)] = META_FUNC(var_sk_bound_if), | ||
| 303 | }, | 516 | }, |
| 304 | [TCF_META_TYPE_INT] = { | 517 | [TCF_META_TYPE_INT] = { |
| 305 | [TCF_META_ID_RANDOM] = { .get = meta_int_random }, | 518 | [META_ID(RANDOM)] = META_FUNC(int_random), |
| 306 | [TCF_META_ID_LOADAVG_0] = { .get = meta_int_loadavg_0 }, | 519 | [META_ID(LOADAVG_0)] = META_FUNC(int_loadavg_0), |
| 307 | [TCF_META_ID_LOADAVG_1] = { .get = meta_int_loadavg_1 }, | 520 | [META_ID(LOADAVG_1)] = META_FUNC(int_loadavg_1), |
| 308 | [TCF_META_ID_LOADAVG_2] = { .get = meta_int_loadavg_2 }, | 521 | [META_ID(LOADAVG_2)] = META_FUNC(int_loadavg_2), |
| 309 | [TCF_META_ID_DEV] = { .get = meta_int_dev }, | 522 | [META_ID(DEV)] = META_FUNC(int_dev), |
| 310 | [TCF_META_ID_INDEV] = { .get = meta_int_indev }, | 523 | [META_ID(INDEV)] = META_FUNC(int_indev), |
| 311 | [TCF_META_ID_REALDEV] = { .get = meta_int_realdev }, | 524 | [META_ID(REALDEV)] = META_FUNC(int_realdev), |
| 312 | [TCF_META_ID_PRIORITY] = { .get = meta_int_priority }, | 525 | [META_ID(PRIORITY)] = META_FUNC(int_priority), |
| 313 | [TCF_META_ID_PROTOCOL] = { .get = meta_int_protocol }, | 526 | [META_ID(PROTOCOL)] = META_FUNC(int_protocol), |
| 314 | [TCF_META_ID_SECURITY] = { .get = meta_int_security }, | 527 | [META_ID(SECURITY)] = META_FUNC(int_security), |
| 315 | [TCF_META_ID_PKTTYPE] = { .get = meta_int_pkttype }, | 528 | [META_ID(PKTTYPE)] = META_FUNC(int_pkttype), |
| 316 | [TCF_META_ID_PKTLEN] = { .get = meta_int_pktlen }, | 529 | [META_ID(PKTLEN)] = META_FUNC(int_pktlen), |
| 317 | [TCF_META_ID_DATALEN] = { .get = meta_int_datalen }, | 530 | [META_ID(DATALEN)] = META_FUNC(int_datalen), |
| 318 | [TCF_META_ID_MACLEN] = { .get = meta_int_maclen }, | 531 | [META_ID(MACLEN)] = META_FUNC(int_maclen), |
| 319 | #ifdef CONFIG_NETFILTER | 532 | #ifdef CONFIG_NETFILTER |
| 320 | [TCF_META_ID_NFMARK] = { .get = meta_int_nfmark }, | 533 | [META_ID(NFMARK)] = META_FUNC(int_nfmark), |
| 321 | #endif | 534 | #endif |
| 322 | [TCF_META_ID_TCINDEX] = { .get = meta_int_tcindex }, | 535 | [META_ID(TCINDEX)] = META_FUNC(int_tcindex), |
| 323 | #ifdef CONFIG_NET_CLS_ACT | 536 | #ifdef CONFIG_NET_CLS_ACT |
| 324 | [TCF_META_ID_TCVERDICT] = { .get = meta_int_tcverd }, | 537 | [META_ID(TCVERDICT)] = META_FUNC(int_tcverd), |
| 325 | [TCF_META_ID_TCCLASSID] = { .get = meta_int_tcclassid }, | 538 | [META_ID(TCCLASSID)] = META_FUNC(int_tcclassid), |
| 326 | #endif | 539 | #endif |
| 327 | #ifdef CONFIG_NET_CLS_ROUTE | 540 | #ifdef CONFIG_NET_CLS_ROUTE |
| 328 | [TCF_META_ID_RTCLASSID] = { .get = meta_int_rtclassid }, | 541 | [META_ID(RTCLASSID)] = META_FUNC(int_rtclassid), |
| 329 | #endif | 542 | #endif |
| 330 | [TCF_META_ID_RTIIF] = { .get = meta_int_rtiif } | 543 | [META_ID(RTIIF)] = META_FUNC(int_rtiif), |
| 544 | [META_ID(SK_FAMILY)] = META_FUNC(int_sk_family), | ||
| 545 | [META_ID(SK_STATE)] = META_FUNC(int_sk_state), | ||
| 546 | [META_ID(SK_REUSE)] = META_FUNC(int_sk_reuse), | ||
| 547 | [META_ID(SK_BOUND_IF)] = META_FUNC(int_sk_bound_if), | ||
| 548 | [META_ID(SK_REFCNT)] = META_FUNC(int_sk_refcnt), | ||
| 549 | [META_ID(SK_RCVBUF)] = META_FUNC(int_sk_rcvbuf), | ||
| 550 | [META_ID(SK_SNDBUF)] = META_FUNC(int_sk_sndbuf), | ||
| 551 | [META_ID(SK_SHUTDOWN)] = META_FUNC(int_sk_shutdown), | ||
| 552 | [META_ID(SK_PROTO)] = META_FUNC(int_sk_proto), | ||
| 553 | [META_ID(SK_TYPE)] = META_FUNC(int_sk_type), | ||
| 554 | [META_ID(SK_RMEM_ALLOC)] = META_FUNC(int_sk_rmem_alloc), | ||
| 555 | [META_ID(SK_WMEM_ALLOC)] = META_FUNC(int_sk_wmem_alloc), | ||
| 556 | [META_ID(SK_OMEM_ALLOC)] = META_FUNC(int_sk_omem_alloc), | ||
| 557 | [META_ID(SK_WMEM_QUEUED)] = META_FUNC(int_sk_wmem_queued), | ||
| 558 | [META_ID(SK_RCV_QLEN)] = META_FUNC(int_sk_rcv_qlen), | ||
| 559 | [META_ID(SK_SND_QLEN)] = META_FUNC(int_sk_snd_qlen), | ||
| 560 | [META_ID(SK_ERR_QLEN)] = META_FUNC(int_sk_err_qlen), | ||
| 561 | [META_ID(SK_FORWARD_ALLOCS)] = META_FUNC(int_sk_fwd_alloc), | ||
| 562 | [META_ID(SK_ALLOCS)] = META_FUNC(int_sk_alloc), | ||
| 563 | [META_ID(SK_ROUTE_CAPS)] = META_FUNC(int_sk_route_caps), | ||
| 564 | [META_ID(SK_HASHENT)] = META_FUNC(int_sk_hashent), | ||
| 565 | [META_ID(SK_LINGERTIME)] = META_FUNC(int_sk_lingertime), | ||
| 566 | [META_ID(SK_ACK_BACKLOG)] = META_FUNC(int_sk_ack_bl), | ||
| 567 | [META_ID(SK_MAX_ACK_BACKLOG)] = META_FUNC(int_sk_max_ack_bl), | ||
| 568 | [META_ID(SK_PRIO)] = META_FUNC(int_sk_prio), | ||
| 569 | [META_ID(SK_RCVLOWAT)] = META_FUNC(int_sk_rcvlowat), | ||
| 570 | [META_ID(SK_RCVTIMEO)] = META_FUNC(int_sk_rcvtimeo), | ||
| 571 | [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo), | ||
| 572 | [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), | ||
| 573 | [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), | ||
| 331 | } | 574 | } |
| 332 | }; | 575 | }; |
| 333 | 576 | ||
