<div style="line-height:1.7;color:#000000;font-size:14px;font-family:arial"><div>Hi All,</div><div>      Recently , we have been trying to find out a suitable way to limit  network traffic generated from the process running in the container. The network <span style="line-height: 1.7;"> type we used for our container is veth. And we have tried TC combined with cgroup net_cls subsystem , which has successfully fulfill our goal . However , </span><span style="line-height: 1.7;"> it requires to add the configurations inside the container. As we will provide the container as a service, and it is obviously unacceptable to allow the end </span><span style="line-height: 1.7;">user modify the bandwidth allocation . </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  Thus , we add a new option to tc command named as "peer", which is an optional option , followed keyword dev , and we made a small modification of the kernel <span style="line-height: 1.7;"> to support this option. </span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  Below is an example of how to use it :</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  related hardware infomation, two ends of the veth device , which is used by the container:</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  lxc.network.name = eth0</div><div><span class="Apple-tab-span" style="white-space:pre">       </span>  lxc.network.veth.pair = veth-vps1</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">    </span>  Add configuration:</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>  tc qdisc add dev peer veth-vps1 root handle 1:0 htb default 4   </div><div><span class="Apple-tab-span" style="white-space:pre">    </span>  tc class add dev  peer veth-vps1 parent 1: classid 1:2 htb rate 3mbit    </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  tc class add dev  peer veth-vps1 parent 1: classid 1:3 htb rate 2mbit</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>  tc class add dev  peer veth-vps1 parent 1: classid 1:4 htb rate 1000mbit</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>  tc filter add dev  peer veth-vps1 protocol ip parent 1:0 prio 1 handle 1£º cgroup</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  Display configuration:</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>  tc -s -d qdisc show dev peer veth-vps1 </div><div><span class="Apple-tab-span" style="white-space:pre">  </span>  tc -s -d class show dev peer veth-vps1 </div><div><span class="Apple-tab-span" style="white-space:pre">  </span>  tc filter show dev peer veth-vps1</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>  <span class="Apple-tab-span" style="white-space:pre">     </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  Delete configuration:</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>  tc qdisc del dev peer veth-vps1 root</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>  tc filter del  dev peer veth-vps1 parent 1: prio 2 cgroup</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>  tc class del dev peer veth-vps1 parent 1: classid 1:3 htb rate 2mbit</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  All of the configurations list above will not operate on veth-vps1 , but on the peer end .</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">   </span>  In this way , we may modify the configures of the other end of the veth type device , no need to know it's device name and in which namespace it is in. Thus <span style="line-height: 1.7;"> we may limit the network traffic of the container from the host, no need to get access to the container.</span></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>  </div><div><span class="Apple-tab-span" style="white-space:pre">      </span>  The modification is based on RHEL6.3 , kernel version: 2.6.32-279.22.1.el6 , iproute version: iproute2-2.6.32</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>  Hope it could help you and any suggestions is welcome.</div><div><br></div><div>related patch:</div><div><div>diff --git a/tc/tc_class.c b/tc/tc_class.c</div><div>index 9d4eea5..c894bf2 100644</div><div>--- a/tc/tc_class.c</div><div>+++ b/tc/tc_class.c</div><div>@@ -51,6 +51,7 @@ int tc_class_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>struct tc_estimator est;</div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>char  d[16];</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>char  k[16];</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>int  flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>memset(&req, 0, sizeof(req));</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>memset(&est, 0, sizeof(est));</div><div>@@ -67,6 +68,10 @@ int tc_class_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                 </span>NEXT_ARG();</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>if (d[0])</div><div> <span class="Apple-tab-span" style="white-space:pre">                              </span>duparg("dev", *argv);</div><div>+<span class="Apple-tab-span" style="white-space:pre">                     </span>if(strcmp(*argv , "peer") == 0){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                          </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                           </span>NEXT_ARG();</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">                      </span>strncpy(d, *argv, sizeof(d)-1);</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>} else if (strcmp(*argv, "classid") == 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">                  </span>__u32 handle;</div><div>@@ -136,6 +141,9 @@ int tc_class_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>fprintf(stderr, "Cannot find device \"%s\"\n", d);</div><div> <span class="Apple-tab-span" style="white-space:pre">                 </span>return 1;</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>}</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>if(flag)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                    </span>req.t.tcm_ifindex |= 0x80000000;</div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span></div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>}</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)</div><div>@@ -236,6 +244,7 @@ int tc_class_list(int argc, char **argv)</div><div> {</div><div> <span class="Apple-tab-span" style="white-space:pre">   </span>struct tcmsg t;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>char d[16];</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>memset(&t, 0, sizeof(t));</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>t.tcm_family = AF_UNSPEC;</div><div>@@ -246,6 +255,10 @@ int tc_class_list(int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                  </span>NEXT_ARG();</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>if (d[0])</div><div> <span class="Apple-tab-span" style="white-space:pre">                              </span>duparg("dev", *argv);</div><div>+<span class="Apple-tab-span" style="white-space:pre">                     </span>if(strcmp(*argv , "peer") == 0){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                          </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                           </span>NEXT_ARG();</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">                      </span>strncpy(d, *argv, sizeof(d)-1);</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>} else if (strcmp(*argv, "qdisc") == 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>NEXT_ARG();</div><div>@@ -291,6 +304,9 @@ int tc_class_list(int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                 </span>return 1;</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>filter_ifindex = t.tcm_ifindex;</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span></div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span>if(flag)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                    </span>t.tcm_ifindex |= 0x80000000;</div><div> <span class="Apple-tab-span" style="white-space:pre">   </span>}</div><div> </div><div>  <span class="Apple-tab-span" style="white-space:pre">        </span>if (rtnl_dump_request(&rth, RTM_GETTCLASS, &t, sizeof(t)) < 0) {</div><div>diff --git a/tc/tc_filter.c b/tc/tc_filter.c</div><div>index 919c57c..bec5b1a 100644</div><div>--- a/tc/tc_filter.c</div><div>+++ b/tc/tc_filter.c</div><div>@@ -60,6 +60,7 @@ int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>char  d[16];</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>char  k[16];</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>struct tc_estimator est;</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>memset(&req, 0, sizeof(req));</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>memset(&est, 0, sizeof(est));</div><div>@@ -80,6 +81,10 @@ int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                        </span>NEXT_ARG();</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>if (d[0])</div><div> <span class="Apple-tab-span" style="white-space:pre">                              </span>duparg("dev", *argv);</div><div>+<span class="Apple-tab-span" style="white-space:pre">                     </span>if(strcmp(*argv , "peer") == 0){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                          </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                           </span>NEXT_ARG();</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">                      </span>strncpy(d, *argv, sizeof(d)-1);</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>} else if (strcmp(*argv, "root") == 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">                     </span>if (req.t.tcm_parent) {</div><div>@@ -165,6 +170,9 @@ int tc_filter_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                 </span>fprintf(stderr, "Cannot find device \"%s\"\n", d);</div><div> <span class="Apple-tab-span" style="white-space:pre">                 </span>return 1;</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>}</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>if(flag)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                    </span>req.t.tcm_ifindex |= 0x80000000;</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>}</div><div> </div><div>  <span class="Apple-tab-span" style="white-space:pre">        </span>if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) {</div><div>@@ -267,6 +275,7 @@ int tc_filter_list(int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>__u32 prio = 0;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>__u32 protocol = 0;</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>char *fhandle = NULL;</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>memset(&t, 0, sizeof(t));</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>t.tcm_family = AF_UNSPEC;</div><div>@@ -277,6 +286,10 @@ int tc_filter_list(int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                 </span>NEXT_ARG();</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>if (d[0])</div><div> <span class="Apple-tab-span" style="white-space:pre">                              </span>duparg("dev", *argv);</div><div>+<span class="Apple-tab-span" style="white-space:pre">                     </span>if(strcmp(*argv , "peer") == 0){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                          </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                           </span>NEXT_ARG();</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">                      </span>strncpy(d, *argv, sizeof(d)-1);</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>} else if (strcmp(*argv, "root") == 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">                     </span>if (t.tcm_parent) {</div><div>@@ -334,6 +347,9 @@ int tc_filter_list(int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                        </span>return 1;</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>filter_ifindex = t.tcm_ifindex;</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span></div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span>if(flag)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                    </span>t.tcm_ifindex |= 0x80000000;</div><div> <span class="Apple-tab-span" style="white-space:pre">   </span>}</div><div> </div><div>  <span class="Apple-tab-span" style="white-space:pre">        </span>if (rtnl_dump_request(&rth, RTM_GETTFILTER, &t, sizeof(t)) < 0) {</div><div>diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c</div><div>index c7f2988..3ee7bf6 100644</div><div>--- a/tc/tc_qdisc.c</div><div>+++ b/tc/tc_qdisc.c</div><div>@@ -59,6 +59,7 @@ int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>struct tcmsg <span class="Apple-tab-span" style="white-space:pre">               </span>t;</div><div> <span class="Apple-tab-span" style="white-space:pre">             </span>char   <span class="Apple-tab-span" style="white-space:pre">                        </span>buf[TCA_BUF_MAX];</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>} req;</div><div>+<span class="Apple-tab-span" style="white-space:pre">      </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>memset(&req, 0, sizeof(req));</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>memset(&stab, 0, sizeof(stab));</div><div>@@ -76,6 +77,10 @@ int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                       </span>NEXT_ARG();</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>if (d[0])</div><div> <span class="Apple-tab-span" style="white-space:pre">                              </span>duparg("dev", *argv);</div><div>+<span class="Apple-tab-span" style="white-space:pre">                     </span>if(strcmp(*argv , "peer") == 0){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                          </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                           </span>NEXT_ARG();</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">                      </span>strncpy(d, *argv, sizeof(d)-1);</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>} else if (strcmp(*argv, "handle") == 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">                   </span>__u32 handle;</div><div>@@ -184,6 +189,9 @@ int tc_qdisc_modify(int cmd, unsigned flags, int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                    </span>return 1;</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>req.t.tcm_ifindex = idx;</div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span></div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span>if(flag)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                    </span>req.t.tcm_ifindex |= 0x80000000;</div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>}</div><div> </div><div>  <span class="Apple-tab-span" style="white-space:pre">        </span>if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)</div><div>@@ -281,6 +289,7 @@ int tc_qdisc_list(int argc, char **argv)</div><div> {</div><div> <span class="Apple-tab-span" style="white-space:pre">   </span>struct tcmsg t;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>char d[16];</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>memset(&t, 0, sizeof(t));</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>t.tcm_family = AF_UNSPEC;</div><div>@@ -289,6 +298,10 @@ int tc_qdisc_list(int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>while (argc > 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">          </span>if (strcmp(*argv, "dev") == 0) {</div><div> <span class="Apple-tab-span" style="white-space:pre">                     </span>NEXT_ARG();</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>if(strcmp(*argv , "peer") == 0){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                          </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                           </span>NEXT_ARG();</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>}</div><div> <span class="Apple-tab-span" style="white-space:pre">                      </span>strncpy(d, *argv, sizeof(d)-1);</div><div> #ifdef TC_H_INGRESS</div><div>                 } else if (strcmp(*argv, "ingress") == 0) {</div><div>@@ -315,7 +328,12 @@ int tc_qdisc_list(int argc, char **argv)</div><div> <span class="Apple-tab-span" style="white-space:pre">                  </span>fprintf(stderr, "Cannot find device \"%s\"\n", d);</div><div> <span class="Apple-tab-span" style="white-space:pre">                 </span>return 1;</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>}</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>if(flag)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                    </span>t.tcm_ifindex |= 0x80000000;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                </span></div><div> <span class="Apple-tab-span" style="white-space:pre">               </span>filter_ifindex = t.tcm_ifindex;</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span></div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>}</div><div> </div><div>  <span class="Apple-tab-span" style="white-space:pre">        </span>if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) {</div></div><div><br></div><div><br></div><div><div>diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h</div><div>index f911ec7..48f21e5 100644</div><div>--- a/include/net/pkt_sched.h</div><div>+++ b/include/net/pkt_sched.h</div><div>@@ -5,6 +5,9 @@</div><div> #include <linux/ktime.h></div><div> #include <net/sch_generic.h></div><div> </div><div>+#define IDX_MASK 0x7FFFFFFFul</div><div>+#define FLG_MASK ~IDX_MASK</div><div>+</div><div> struct qdisc_walker</div><div> {</div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>int<span class="Apple-tab-span" style="white-space:pre"> </span>stop;</div><div>@@ -112,4 +115,6 @@ static inline unsigned psched_mtu(const struct net_device *dev)</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>return dev->mtu + dev->hard_header_len;</div><div> }</div><div> </div><div>+int inline get_peer_dev(struct net_device** dev);</div><div>+</div><div> #endif</div><div>diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c</div><div>index 7cf6c0f..19909bf 100644</div><div>--- a/net/sched/cls_api.c</div><div>+++ b/net/sched/cls_api.c</div><div>@@ -136,6 +136,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>unsigned long fh;</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>int err;</div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>int tp_created = 0;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>if (net != &init_net)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>return -EINVAL;</div><div>@@ -158,10 +159,21 @@ replay:</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>/* Find head of filter chain. */</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>/* Find link */</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span>if(t->tcm_ifindex & FLG_MASK){</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>t->tcm_ifindex &= IDX_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">  </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>dev = __dev_get_by_index(&init_net, t->tcm_ifindex);</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>if (dev == NULL)</div><div> <span class="Apple-tab-span" style="white-space:pre">               </span>return -ENODEV;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>if(flag) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>if(err < 0)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                      </span>return err;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL);</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>if (err < 0)</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>return err;</div><div>@@ -416,15 +428,29 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)</div><div> <span class="Apple-tab-span" style="white-space:pre">   </span>unsigned long cl = 0;</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>const struct Qdisc_class_ops *cops;</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>struct tcf_dump_args arg;</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>int flag = 0;</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>int err = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>if (net != &init_net)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>return 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))</div><div> <span class="Apple-tab-span" style="white-space:pre">          </span>return skb->len;</div><div>-<span class="Apple-tab-span" style="white-space:pre"> </span>if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span></div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>if(tcm->tcm_ifindex & FLG_MASK){</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>tcm->tcm_ifindex &= IDX_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div> <span class="Apple-tab-span" style="white-space:pre">            </span>return skb->len;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>if(flag) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>if(err < 0)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                      </span>return err;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>if (!tcm->tcm_parent)</div><div> <span class="Apple-tab-span" style="white-space:pre">               </span>q = dev->qdisc;</div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>else</div><div>diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c</div><div>index 6cc404e..c5d663a 100644</div><div>--- a/net/sched/sch_api.c</div><div>+++ b/net/sched/sch_api.c</div><div>@@ -948,6 +948,23 @@ check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>return 0;</div><div> }</div><div> </div><div>+int inline get_peer_dev(struct net_device** dev)</div><div>+{</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>struct net_device* end = *dev;</div><div>+<span class="Apple-tab-span" style="white-space:pre">      </span>int err = -EINVAL;</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">  </span>if(!end)</div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span>return err;</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>if(end->rtnl_link_ops && !strcmp(end->rtnl_link_ops->kind , "veth")){</div><div>+<span class="Apple-tab-span" style="white-space:pre">            </span>*dev = *(struct net_device**)netdev_priv(end);</div><div>+<span class="Apple-tab-span" style="white-space:pre">              </span>err = 0;</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>}</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>return err;</div><div>+}</div><div>+EXPORT_SYMBOL(get_peer_dev);</div><div>+</div><div> /*</div><div>  * Delete/get qdisc.</div><div>  */</div><div>@@ -962,13 +979,25 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)</div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>struct Qdisc *q = NULL;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>struct Qdisc *p = NULL;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>int err;</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>if (net != &init_net)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>return -EINVAL;</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span></div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>if(tcm->tcm_ifindex & FLG_MASK){</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>tcm->tcm_ifindex &= IDX_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div> <span class="Apple-tab-span" style="white-space:pre">            </span>return -ENODEV;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>if(flag) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>if(err < 0)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                      </span>return err;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>if (err < 0)</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>return err;</div><div>@@ -1024,6 +1053,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)</div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>u32 clid;</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>struct Qdisc *q, *p;</div><div> <span class="Apple-tab-span" style="white-space:pre">   </span>int err;</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>if (net != &init_net)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>return -EINVAL;</div><div>@@ -1034,9 +1064,20 @@ replay:</div><div> <span class="Apple-tab-span" style="white-space:pre">   </span>clid = tcm->tcm_parent;</div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>q = p = NULL;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">  </span>if(tcm->tcm_ifindex & FLG_MASK){</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>tcm->tcm_ifindex &= IDX_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div> <span class="Apple-tab-span" style="white-space:pre">            </span>return -ENODEV;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>if(flag) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>if(err < 0)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                      </span>return err;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>if (err < 0)</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>return err;</div><div>@@ -1169,6 +1210,10 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>struct nlmsghdr  *nlh;</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>unsigned char *b = skb_tail_pointer(skb);</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>struct gnet_dump d;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>struct net *skb_net;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>struct net *dev_net;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>struct net_device *dev;</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span>int err;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>tcm = NLMSG_DATA(nlh);</div><div>@@ -1184,6 +1229,20 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,</div><div> <span class="Apple-tab-span" style="white-space:pre">           </span>goto nla_put_failure;</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>q->qstats.qlen = q->q.qlen;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">      </span>if(skb->sk){</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>skb_net = sock_net(skb->sk);</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>dev_net = qdisc_dev(q)->nd_net;</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>if( skb_net != dev_net ){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                   </span>dev = qdisc_dev(q);</div><div>+<span class="Apple-tab-span" style="white-space:pre">                 </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">                       </span>if(!err){</div><div>+<span class="Apple-tab-span" style="white-space:pre">                           </span>tcm->tcm_ifindex = dev->ifindex;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                              </span>tcm->tcm_ifindex |= FLG_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">                    </span>}</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>}</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>}</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span></div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>if (q->stab && qdisc_dump_stab(skb, q->stab) < 0)</div><div> <span class="Apple-tab-span" style="white-space:pre">             </span>goto nla_put_failure;</div><div> </div><div>@@ -1285,19 +1344,38 @@ done:</div><div> </div><div> static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)</div><div> {</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);</div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>struct net *net = sock_net(skb->sk);</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>int idx, q_idx;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>int s_idx, s_q_idx;</div><div> <span class="Apple-tab-span" style="white-space:pre">    </span>struct net_device *dev;</div><div>-</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span>int flag = 0;</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>int err = 0;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span></div><div> <span class="Apple-tab-span" style="white-space:pre">       </span>if (net != &init_net)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>return 0;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">      </span>if(tcm->tcm_ifindex & FLG_MASK){</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>tcm->tcm_ifindex &= IDX_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div>+<span class="Apple-tab-span" style="white-space:pre">         </span>return -ENODEV;</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span>if(flag) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>if(err < 0)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                      </span>return err;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>net = dev->nd_net;</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>s_idx = cb->args[0];</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>s_q_idx = q_idx = cb->args[1];</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>read_lock(&dev_base_lock);</div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>idx = 0;</div><div>-<span class="Apple-tab-span" style="white-space:pre">    </span>for_each_netdev(&init_net, dev) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>for_each_netdev(net, dev) {</div><div> <span class="Apple-tab-span" style="white-space:pre">            </span>struct netdev_queue *dev_queue;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">           </span>if (idx < s_idx)</div><div>@@ -1348,13 +1426,25 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)</div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>u32 clid = tcm->tcm_handle;</div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>u32 qid = TC_H_MAJ(clid);</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>int err;</div><div>+<span class="Apple-tab-span" style="white-space:pre">    </span>int flag = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">     </span>if (net != &init_net)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>return -EINVAL;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>if(tcm->tcm_ifindex & FLG_MASK){</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>tcm->tcm_ifindex &= IDX_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div> <span class="Apple-tab-span" style="white-space:pre">            </span>return -ENODEV;</div><div> </div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>if(flag) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>if(err < 0)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                      </span>return err;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div>+</div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>if (err < 0)</div><div> <span class="Apple-tab-span" style="white-space:pre">                </span>return err;</div><div>@@ -1590,14 +1680,28 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>struct netdev_queue *dev_queue;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>struct net_device *dev;</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>int t, s_t;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>int flag = 0;</div><div>+<span class="Apple-tab-span" style="white-space:pre">       </span>int err = 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre">      </span>if (net != &init_net)</div><div> <span class="Apple-tab-span" style="white-space:pre">              </span>return 0;</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))</div><div> <span class="Apple-tab-span" style="white-space:pre">          </span>return 0;</div><div>-<span class="Apple-tab-span" style="white-space:pre">   </span>if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div>-<span class="Apple-tab-span" style="white-space:pre">           </span>return 0;</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>if(tcm->tcm_ifindex & FLG_MASK){</div><div>+<span class="Apple-tab-span" style="white-space:pre">             </span>flag = 1;</div><div>+<span class="Apple-tab-span" style="white-space:pre">           </span>tcm->tcm_ifindex &= IDX_MASK;</div><div>+<span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">   </span>if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)</div><div>+<span class="Apple-tab-span" style="white-space:pre">         </span>return -ENODEV;</div><div>+</div><div>+<span class="Apple-tab-span" style="white-space:pre">     </span>if(flag) {</div><div>+<span class="Apple-tab-span" style="white-space:pre">          </span>err = get_peer_dev(&dev);</div><div>+<span class="Apple-tab-span" style="white-space:pre">               </span>if(err < 0)</div><div>+<span class="Apple-tab-span" style="white-space:pre">                      </span>return err;</div><div>+<span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div> </div><div> <span class="Apple-tab-span" style="white-space:pre"> </span>s_t = cb->args[0];</div><div> <span class="Apple-tab-span" style="white-space:pre">  </span>t = 0;</div></div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre">  </span>  </div><div><br></div></div>