X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnetdev-linux.c;h=0c5ba8b85c81fa969601b8e047648a9483dcc64a;hb=e61c056cb94aeffc86cb314ea32726be9b666724;hp=e1a3c8c46d9c41111aa6f4819566cd32646bb2db;hpb=4e8e4213a815a30216e855a805a8bcd5b8c5a886;p=openvswitch diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index e1a3c8c4..0c5ba8b8 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -63,7 +63,7 @@ #include "svec.h" #include "vlog.h" -VLOG_DEFINE_THIS_MODULE(netdev_linux) +VLOG_DEFINE_THIS_MODULE(netdev_linux); /* These were introduced in Linux 2.6.14, so they might be missing if we have * old headers. */ @@ -487,8 +487,9 @@ netdev_linux_cache_cb(const struct rtnetlink_change *change, /* Creates the netdev device of 'type' with 'name'. */ static int -netdev_linux_create_system(const char *name, const char *type OVS_UNUSED, - const struct shash *args, struct netdev_dev **netdev_devp) +netdev_linux_create_system(const struct netdev_class *class OVS_UNUSED, + const char *name, const struct shash *args, + struct netdev_dev **netdev_devp) { struct netdev_dev_linux *netdev_dev; int error; @@ -520,8 +521,9 @@ netdev_linux_create_system(const char *name, const char *type OVS_UNUSED, * buffers, across all readers. Therefore once data is read it will * be unavailable to other reads for tap devices. */ static int -netdev_linux_create_tap(const char *name, const char *type OVS_UNUSED, - const struct shash *args, struct netdev_dev **netdev_devp) +netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED, + const char *name, const struct shash *args, + struct netdev_dev **netdev_devp) { struct netdev_dev_linux *netdev_dev; struct tap_state *state; @@ -1367,6 +1369,9 @@ netdev_linux_remove_policing(struct netdev *netdev) int error; tcmsg = tc_make_request(netdev, RTM_DELQDISC, 0, &request); + if (!tcmsg) { + return ENODEV; + } tcmsg->tcm_handle = tc_make_handle(0xffff, 0); tcmsg->tcm_parent = TC_H_INGRESS; nl_msg_put_string(&request, TCA_KIND, "ingress"); @@ -1646,16 +1651,20 @@ netdev_linux_get_queue_stats(const struct netdev *netdev, } } -static void +static bool start_queue_dump(const struct netdev *netdev, struct nl_dump *dump) { struct ofpbuf request; struct tcmsg *tcmsg; tcmsg = tc_make_request(netdev, RTM_GETTCLASS, 0, &request); + if (!tcmsg) { + return false; + } tcmsg->tcm_parent = 0; nl_dump_start(dump, rtnl_sock, &request); ofpbuf_uninit(&request); + return true; } static int @@ -1712,7 +1721,9 @@ netdev_linux_dump_queue_stats(const struct netdev *netdev, } last_error = 0; - start_queue_dump(netdev, &dump); + if (!start_queue_dump(netdev, &dump)) { + return ENODEV; + } while (nl_dump_next(&dump, &msg)) { error = netdev_dev->tc->ops->class_dump_stats(netdev, &msg, cb, aux); if (error) { @@ -2266,6 +2277,9 @@ htb_setup_qdisc__(struct netdev *netdev) tcmsg = tc_make_request(netdev, RTM_NEWQDISC, NLM_F_EXCL | NLM_F_CREATE, &request); + if (!tcmsg) { + return ENODEV; + } tcmsg->tcm_handle = tc_make_handle(1, 0); tcmsg->tcm_parent = TC_H_ROOT; @@ -2274,7 +2288,7 @@ htb_setup_qdisc__(struct netdev *netdev) memset(&opt, 0, sizeof opt); opt.rate2quantum = 10; opt.version = 3; - opt.defcls = 0; + opt.defcls = 1; opt_offset = nl_msg_start_nested(&request, TCA_OPTIONS); nl_msg_put_unspec(&request, TCA_HTB_INIT, &opt, sizeof opt); @@ -2306,6 +2320,9 @@ htb_setup_class__(struct netdev *netdev, unsigned int handle, opt.prio = class->priority; tcmsg = tc_make_request(netdev, RTM_NEWTCLASS, NLM_F_CREATE, &request); + if (!tcmsg) { + return ENODEV; + } tcmsg->tcm_handle = handle; tcmsg->tcm_parent = parent; @@ -2413,13 +2430,13 @@ htb_parse_class_details__(struct netdev *netdev, const char *priority_s = shash_find_data(details, "priority"); int mtu; - /* min-rate */ + /* min-rate. Don't allow a min-rate below 1500 bytes/s. */ if (!min_rate_s) { /* min-rate is required. */ return EINVAL; } hc->min_rate = strtoull(min_rate_s, NULL, 10) / 8; - hc->min_rate = MAX(hc->min_rate, 0); + hc->min_rate = MAX(hc->min_rate, 1500); hc->min_rate = MIN(hc->min_rate, htb->max_rate); /* max-rate */ @@ -2517,7 +2534,6 @@ htb_update_queue__(struct netdev *netdev, unsigned int queue_id, static int htb_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED) { - struct shash details = SHASH_INITIALIZER(&details); struct ofpbuf msg; struct nl_dump dump; struct htb_class hc; @@ -2529,8 +2545,9 @@ htb_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED) htb = htb_install__(netdev, hc.max_rate); /* Get queues. */ - start_queue_dump(netdev, &dump); - shash_init(&details); + if (!start_queue_dump(netdev, &dump)) { + return ENODEV; + } while (nl_dump_next(&dump, &msg)) { unsigned int queue_id; @@ -2659,7 +2676,7 @@ htb_class_dump_stats(const struct netdev *netdev OVS_UNUSED, major = tc_get_major(handle); minor = tc_get_minor(handle); if (major == 1 && minor > 0 && minor <= HTB_N_QUEUES) { - (*cb)(tc_get_minor(handle), &stats, aux); + (*cb)(minor - 1, &stats, aux); } return 0; } @@ -2936,7 +2953,7 @@ tc_bytes_to_ticks(unsigned int rate, unsigned int size) if (!buffer_hz) { read_psched(); } - return ((unsigned long long int) ticks_per_s * size) / rate; + return rate ? ((unsigned long long int) ticks_per_s * size) / rate : 0; } /* Returns the number of bytes that need to be reserved for qdisc buffering at @@ -3082,6 +3099,9 @@ tc_query_class(const struct netdev *netdev, int error; tcmsg = tc_make_request(netdev, RTM_GETTCLASS, NLM_F_ECHO, &request); + if (!tcmsg) { + return ENODEV; + } tcmsg->tcm_handle = handle; tcmsg->tcm_parent = parent; @@ -3105,6 +3125,9 @@ tc_delete_class(const struct netdev *netdev, unsigned int handle) int error; tcmsg = tc_make_request(netdev, RTM_DELTCLASS, 0, &request); + if (!tcmsg) { + return ENODEV; + } tcmsg->tcm_handle = handle; tcmsg->tcm_parent = 0; @@ -3129,6 +3152,9 @@ tc_del_qdisc(struct netdev *netdev) int error; tcmsg = tc_make_request(netdev, RTM_DELQDISC, 0, &request); + if (!tcmsg) { + return ENODEV; + } tcmsg->tcm_handle = tc_make_handle(1, 0); tcmsg->tcm_parent = TC_H_ROOT; @@ -3180,6 +3206,9 @@ tc_query_qdisc(const struct netdev *netdev) * We could check for Linux 2.6.35+ and use a more straightforward method * there. */ tcmsg = tc_make_request(netdev, RTM_GETQDISC, NLM_F_ECHO, &request); + if (!tcmsg) { + return ENODEV; + } tcmsg->tcm_handle = tc_make_handle(1, 0); tcmsg->tcm_parent = 0; @@ -3282,9 +3311,7 @@ tc_put_rtab(struct ofpbuf *msg, uint16_t type, const struct tc_ratespec *rate) /* Calculates the proper value of 'buffer' or 'cbuffer' in HTB options given a * rate of 'Bps' bytes per second, the specified 'mtu', and a user-requested * burst size of 'burst_bytes'. (If no value was requested, a 'burst_bytes' of - * 0 is fine.) - * - * This */ + * 0 is fine.) */ static int tc_calc_buffer(unsigned int Bps, int mtu, uint64_t burst_bytes) {