[Patch v2 1/2] tc: save error code for rtnl_tc_data_check()

Cong Wang xiyou.wangcong at gmail.com
Mon Jul 28 15:21:00 PDT 2014


Cc: Thomas Graf <tgraf at suug.ch>
Cc: Thomas Haller <thaller at redhat.com>
Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 include/netlink-private/route/tc-api.h |  2 +-
 lib/route/qdisc/htb.c                  | 80 ++++++++++++++++++++--------------
 lib/route/tc.c                         | 15 ++++++-
 3 files changed, 61 insertions(+), 36 deletions(-)

diff --git a/include/netlink-private/route/tc-api.h b/include/netlink-private/route/tc-api.h
index bf0c8a3..ce62080 100644
--- a/include/netlink-private/route/tc-api.h
+++ b/include/netlink-private/route/tc-api.h
@@ -116,7 +116,7 @@ extern int			rtnl_tc_compare(struct nl_object *,
 
 extern void *			rtnl_tc_data(struct rtnl_tc *);
 extern void *			rtnl_tc_data_check(struct rtnl_tc *,
-						   struct rtnl_tc_ops *);
+						   struct rtnl_tc_ops *, int *);
 
 extern struct rtnl_tc_ops *	rtnl_tc_lookup_ops(enum rtnl_tc_type,
 						   const char *);
diff --git a/lib/route/qdisc/htb.c b/lib/route/qdisc/htb.c
index 5a61a4e..c018f48 100644
--- a/lib/route/qdisc/htb.c
+++ b/lib/route/qdisc/htb.c
@@ -269,14 +269,14 @@ nla_put_failure:
 static struct rtnl_tc_ops htb_qdisc_ops;
 static struct rtnl_tc_ops htb_class_ops;
 
-static struct rtnl_htb_qdisc *htb_qdisc_data(struct rtnl_qdisc *qdisc)
+static struct rtnl_htb_qdisc *htb_qdisc_data(struct rtnl_qdisc *qdisc, int *err)
 {
-	return rtnl_tc_data_check(TC_CAST(qdisc), &htb_qdisc_ops);
+	return rtnl_tc_data_check(TC_CAST(qdisc), &htb_qdisc_ops, err);
 }
 
-static struct rtnl_htb_class *htb_class_data(struct rtnl_class *class)
+static struct rtnl_htb_class *htb_class_data(struct rtnl_class *class, int *err)
 {
-	return rtnl_tc_data_check(TC_CAST(class), &htb_class_ops);
+	return rtnl_tc_data_check(TC_CAST(class), &htb_class_ops, err);
 }
 
 /**
@@ -294,8 +294,8 @@ uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *qdisc)
 {
 	struct rtnl_htb_qdisc *htb;
 
-	if ((htb = htb_qdisc_data(qdisc)) &&
-	    htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM)
+	if ((htb = htb_qdisc_data(qdisc, NULL)) &&
+	    (htb->qh_mask & SCH_HTB_HAS_RATE2QUANTUM))
 		return htb->qh_rate2quantum;
 
 	return 0;
@@ -304,9 +304,10 @@ uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *qdisc)
 int rtnl_htb_set_rate2quantum(struct rtnl_qdisc *qdisc, uint32_t rate2quantum)
 {
 	struct rtnl_htb_qdisc *htb;
+	int err;
 
-	if (!(htb = htb_qdisc_data(qdisc)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_qdisc_data(qdisc, &err)))
+		return err;
 
 	htb->qh_rate2quantum = rate2quantum;
 	htb->qh_mask |= SCH_HTB_HAS_RATE2QUANTUM;
@@ -327,7 +328,7 @@ uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *qdisc)
 {
 	struct rtnl_htb_qdisc *htb;
 
-	if ((htb = htb_qdisc_data(qdisc)) &&
+	if ((htb = htb_qdisc_data(qdisc, NULL)) &&
 	    htb->qh_mask & SCH_HTB_HAS_DEFCLS)
 		return htb->qh_defcls;
 
@@ -342,9 +343,10 @@ uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *qdisc)
 int rtnl_htb_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls)
 {
 	struct rtnl_htb_qdisc *htb;
+	int err;
 
-	if (!(htb = htb_qdisc_data(qdisc)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_qdisc_data(qdisc, &err)))
+		return err;
 
 	htb->qh_defcls = defcls;
 	htb->qh_mask |= SCH_HTB_HAS_DEFCLS;
@@ -356,7 +358,8 @@ uint32_t rtnl_htb_get_prio(struct rtnl_class *class)
 {
 	struct rtnl_htb_class *htb;
 
-	if ((htb = htb_class_data(class)) && htb->ch_mask & SCH_HTB_HAS_PRIO)
+	if ((htb = htb_class_data(class, NULL)) &&
+	    (htb->ch_mask & SCH_HTB_HAS_PRIO))
 		return htb->ch_prio;
 
 	return 0;
@@ -365,9 +368,10 @@ uint32_t rtnl_htb_get_prio(struct rtnl_class *class)
 int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio)
 {
 	struct rtnl_htb_class *htb;
+	int err;
 
-	if (!(htb = htb_class_data(class)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_class_data(class, &err)))
+		return err;
 
 	htb->ch_prio = prio;
 	htb->ch_mask |= SCH_HTB_HAS_PRIO;
@@ -385,7 +389,8 @@ uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
 {
 	struct rtnl_htb_class *htb;
 
-	if ((htb = htb_class_data(class)) && htb->ch_mask & SCH_HTB_HAS_RATE)
+	if ((htb = htb_class_data(class, NULL)) &&
+	    (htb->ch_mask & SCH_HTB_HAS_RATE))
 		return htb->ch_rate.rs_rate;
 
 	return 0;
@@ -401,9 +406,10 @@ uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
 int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
 {
 	struct rtnl_htb_class *htb;
+	int err;
 
-	if (!(htb = htb_class_data(class)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_class_data(class, &err)))
+		return err;
 
 	htb->ch_rate.rs_cell_log = UINT8_MAX; /* use default value */
 	htb->ch_rate.rs_rate = rate;
@@ -422,7 +428,8 @@ uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
 {
 	struct rtnl_htb_class *htb;
 
-	if ((htb = htb_class_data(class)) && htb->ch_mask & SCH_HTB_HAS_CEIL)
+	if ((htb = htb_class_data(class, NULL)) &&
+	    (htb->ch_mask & SCH_HTB_HAS_CEIL))
 		return htb->ch_ceil.rs_rate;
 
 	return 0;
@@ -438,9 +445,10 @@ uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
 int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
 {
 	struct rtnl_htb_class *htb;
+	int err;
 
-	if (!(htb = htb_class_data(class)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_class_data(class, &err)))
+		return err;
 
 	htb->ch_ceil.rs_cell_log = UINT8_MAX; /* use default value */
 	htb->ch_ceil.rs_rate = ceil;
@@ -459,7 +467,7 @@ uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *class)
 {
 	struct rtnl_htb_class *htb;
 
-	if ((htb = htb_class_data(class)) &&
+	if ((htb = htb_class_data(class, NULL)) &&
 	     htb->ch_mask & SCH_HTB_HAS_RBUFFER)
 		return htb->ch_rbuffer;
 
@@ -474,9 +482,10 @@ uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *class)
 int rtnl_htb_set_rbuffer(struct rtnl_class *class, uint32_t rbuffer)
 {
 	struct rtnl_htb_class *htb;
+	int err;
 
-	if (!(htb = htb_class_data(class)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_class_data(class, &err)))
+		return err;
 
 	htb->ch_rbuffer = rbuffer;
 	htb->ch_mask |= SCH_HTB_HAS_RBUFFER;
@@ -494,7 +503,7 @@ uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *class)
 {
 	struct rtnl_htb_class *htb;
 
-	if ((htb = htb_class_data(class)) &&
+	if ((htb = htb_class_data(class, NULL)) &&
 	     htb->ch_mask & SCH_HTB_HAS_CBUFFER)
 		return htb->ch_cbuffer;
 
@@ -509,9 +518,10 @@ uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *class)
 int rtnl_htb_set_cbuffer(struct rtnl_class *class, uint32_t cbuffer)
 {
 	struct rtnl_htb_class *htb;
+	int err;
 
-	if (!(htb = htb_class_data(class)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_class_data(class, &err)))
+		return err;
 
 	htb->ch_cbuffer = cbuffer;
 	htb->ch_mask |= SCH_HTB_HAS_CBUFFER;
@@ -531,7 +541,7 @@ uint32_t rtnl_htb_get_quantum(struct rtnl_class *class)
 {
 	struct rtnl_htb_class *htb;
 
-	if ((htb = htb_class_data(class)) &&
+	if ((htb = htb_class_data(class, NULL)) &&
 	    htb->ch_mask & SCH_HTB_HAS_QUANTUM)
 		return htb->ch_quantum;
 
@@ -550,9 +560,10 @@ uint32_t rtnl_htb_get_quantum(struct rtnl_class *class)
 int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum)
 {
 	struct rtnl_htb_class *htb;
+	int err;
 
-	if (!(htb = htb_class_data(class)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_class_data(class, &err)))
+		return err;
 
 	htb->ch_quantum = quantum;
 	htb->ch_mask |= SCH_HTB_HAS_QUANTUM;
@@ -573,11 +584,13 @@ int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum)
 int rtnl_htb_get_level(struct rtnl_class *class)
 {
 	struct rtnl_htb_class *htb;
+	int err = -NLE_OPNOTSUPP;
 
-	if ((htb = htb_class_data(class)) && htb->ch_mask & SCH_HTB_HAS_LEVEL)
+	if ((htb = htb_class_data(class, &err)) &&
+	    (htb->ch_mask & SCH_HTB_HAS_LEVEL))
 		return htb->ch_level;
 
-	return -NLE_OPNOTSUPP;
+	return err;
 }
 
 /**
@@ -595,9 +608,10 @@ int rtnl_htb_get_level(struct rtnl_class *class)
 int rtnl_htb_set_level(struct rtnl_class *class, int level)
 {
 	struct rtnl_htb_class *htb;
+	int err;
 
-	if (!(htb = htb_class_data(class)))
-		return -NLE_OPNOTSUPP;
+	if (!(htb = htb_class_data(class, &err)))
+		return err;
 
 	htb->ch_level = level;
 	htb->ch_mask |= SCH_HTB_HAS_LEVEL;
diff --git a/lib/route/tc.c b/lib/route/tc.c
index 0f150cc..34c3b57 100644
--- a/lib/route/tc.c
+++ b/lib/route/tc.c
@@ -1030,6 +1030,7 @@ void *rtnl_tc_data(struct rtnl_tc *tc)
  * Check traffic control object type and return private data section 
  * @arg tc		traffic control object
  * @arg ops		expected traffic control object operations
+ * @arg err		the place where saves the error code if fails
  *
  * Checks whether the traffic control object matches the type
  * specified with the traffic control object operations. If the
@@ -1040,8 +1041,10 @@ void *rtnl_tc_data(struct rtnl_tc *tc)
  *
  * @return Pointer to private tc data or NULL if type mismatches.
  */
-void *rtnl_tc_data_check(struct rtnl_tc *tc, struct rtnl_tc_ops *ops)
+void *rtnl_tc_data_check(struct rtnl_tc *tc, struct rtnl_tc_ops *ops, int *err)
 {
+	void *ret;
+
 	if (tc->tc_ops != ops) {
 		char buf[64];
 
@@ -1050,10 +1053,18 @@ void *rtnl_tc_data_check(struct rtnl_tc *tc, struct rtnl_tc_ops *ops)
 			 tc, ops->to_kind, tc->tc_ops->to_kind);
 		APPBUG(buf);
 
+		if (err)
+			*err = -NLE_OPNOTSUPP;
 		return NULL;
 	}
 
-	return rtnl_tc_data(tc);
+	ret = rtnl_tc_data(tc);
+	if (ret == NULL) {
+		if (err)
+			*err = -NLE_NOMEM;
+	}
+
+	return ret;
 }
 
 struct nl_af_group tc_groups[] = {
-- 
1.8.3.1




More information about the libnl mailing list