Chinaunix首页 | 论坛 | 博客

v.t

  • 博客访问: 17468
  • 博文数量: 1
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 16
  • 用 户 组: 普通用户
  • 注册时间: 2019-04-05 15:39
文章分类

分类: LINUX

2019-04-05 21:37:09

linux内核学习,有不足之处欢迎大家一起探讨
1.网桥创建
br_init   注册ioctrl操作函数  br_ioctl_deviceless_stub ,在br_ioctl_deviceless_stub函数中可以创建一个新的虚拟网桥设备,并绑定另一个ioctrl操作函数 br_dev_ioctl ,br_dev_ioctl 函数可以增加或者删除一个'接口' (add_del_if) ,在br_add_if中注册报文处理函数br_handle_frame
2.网桥处理报文
__netif_receive_skb_core 调用 br_handle_frame

3.注册及收包如图:




4.部分函数
4.1 static int __init br_init(void)

点击(此处)折叠或打开

  1. static int __init br_init(void)
  2. {
  3.     int err;

  4.     BUILD_BUG_ON(sizeof(struct br_input_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb));

  5.     err = stp_proto_register(&br_stp_proto);
  6.     if (err < 0) {
  7.         pr_err("bridge: can't register sap for STP\n");
  8.         return err;
  9.     }

  10.     err = br_fdb_init();
  11.     if (err)
  12.         goto err_out;

  13.     err = register_pernet_subsys(&br_net_ops);
  14.     if (err)
  15.         goto err_out1;

  16.     err = br_nf_core_init();
  17.     if (err)
  18.         goto err_out2;

  19.     err = register_netdevice_notifier(&br_device_notifier);
  20.     if (err)
  21.         goto err_out3;

  22.     err = register_switchdev_notifier(&br_switchdev_notifier);
  23.     if (err)
  24.         goto err_out4;

  25.     err = br_netlink_init();
  26.     if (err)
  27.         goto err_out5;

  28.     brioctl_set(br_ioctl_deviceless_stub);

  29. #if IS_ENABLED(CONFIG_ATM_LANE)
  30.     br_fdb_test_addr_hook = br_fdb_test_addr;
  31. #endif

  32. #if IS_MODULE(CONFIG_BRIDGE_NETFILTER)
  33.     pr_info("bridge: filtering via arp/ip/ip6tables is no longer available "
  34.         "by default. Update your scripts to load br_netfilter if you "
  35.         "need this.\n");
  36. #endif

  37.     return 0;

  38. err_out5:
  39.     unregister_switchdev_notifier(&br_switchdev_notifier);
  40. err_out4:
  41.     unregister_netdevice_notifier(&br_device_notifier);
  42. err_out3:
  43.     br_nf_core_fini();
  44. err_out2:
  45.     unregister_pernet_subsys(&br_net_ops);
  46. err_out1:
  47.     br_fdb_fini();
  48. err_out:
  49.     stp_proto_unregister(&br_stp_proto);
  50.     return err;
  51. }

  52. module_init(br_init)

4.2 
int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg)

点击(此处)折叠或打开

  1. int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg)
  2. {
  3.     switch (cmd) {
  4.     case SIOCGIFBR:
  5.     case SIOCSIFBR:
  6.         return old_deviceless(net, uarg);

  7.     case SIOCBRADDBR:
  8.     case SIOCBRDELBR:
  9.     {
  10.         char buf[IFNAMSIZ];

  11.         if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
  12.             return -EPERM;

  13.         if (copy_from_user(buf, uarg, IFNAMSIZ))
  14.             return -EFAULT;

  15.         buf[IFNAMSIZ-1] = 0;
  16.         if (cmd == SIOCBRADDBR)
  17.             return br_add_bridge(net, buf);

  18.         return br_del_bridge(net, buf);
  19.     }
  20.     }
  21.     return -EOPNOTSUPP;
  22. }

4.3 int br_add_bridge(struct net *net, const char *name)

点击(此处)折叠或打开

  1. int br_add_bridge(struct net *net, const char *name)
  2. {
  3.     struct net_device *dev;
  4.     int res;

  5.     dev = alloc_netdev(sizeof(struct net_bridge), name, NET_NAME_UNKNOWN,
  6.              br_dev_setup);

  7.     if (!dev)
  8.         return -ENOMEM;

  9.     dev_net_set(dev, net);
  10.     dev->rtnl_link_ops = &br_link_ops;

  11.     res = register_netdev(dev);
  12.     if (res)
  13.         free_netdev(dev);
  14.     return res;
  15. }

4.4 void br_dev_setup(struct net_device *dev)

点击(此处)折叠或打开

  1. void br_dev_setup(struct net_device *dev)
  2. {
  3.     struct net_bridge *br = netdev_priv(dev);

  4.     eth_hw_addr_random(dev);
  5.     ether_setup(dev);

  6.     dev->netdev_ops = &br_netdev_ops;
  7.     dev->needs_free_netdev = true;
  8.     dev->ethtool_ops = &br_ethtool_ops;
  9.     SET_NETDEV_DEVTYPE(dev, &br_type);
  10.     dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;

  11.     dev->features = COMMON_FEATURES | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL |
  12.             NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
  13.     dev->hw_features = COMMON_FEATURES | NETIF_F_HW_VLAN_CTAG_TX |
  14.              NETIF_F_HW_VLAN_STAG_TX;
  15.     dev->vlan_features = COMMON_FEATURES;

  16.     br->dev = dev;
  17.     spin_lock_init(&br->lock);
  18.     INIT_LIST_HEAD(&br->port_list);
  19.     INIT_HLIST_HEAD(&br->fdb_list);
  20.     spin_lock_init(&br->hash_lock);

  21.     br->bridge_id.prio[0] = 0x80;
  22.     br->bridge_id.prio[1] = 0x00;

  23.     ether_addr_copy(br->group_addr, eth_stp_addr);

  24.     br->stp_enabled = BR_NO_STP;
  25.     br->group_fwd_mask = BR_GROUPFWD_DEFAULT;
  26.     br->group_fwd_mask_required = BR_GROUPFWD_DEFAULT;

  27.     br->designated_root = br->bridge_id;
  28.     br->bridge_max_age = br->max_age = 20 * HZ;
  29.     br->bridge_hello_time = br->hello_time = 2 * HZ;
  30.     br->bridge_forward_delay = br->forward_delay = 15 * HZ;
  31.     br->bridge_ageing_time = br->ageing_time = BR_DEFAULT_AGEING_TIME;
  32.     dev->max_mtu = ETH_MAX_MTU;

  33.     br_netfilter_rtable_init(br);
  34.     br_stp_timer_init(br);
  35.     br_multicast_init(br);
  36.     INIT_DELAYED_WORK(&br->gc_work, br_fdb_cleanup);
  37. }

4.5 static const struct net_device_ops br_netdev_ops

点击(此处)折叠或打开

  1. static const struct net_device_ops br_netdev_ops = {
  2.     .ndo_open         = br_dev_open,
  3.     .ndo_stop         = br_dev_stop,
  4.     .ndo_init         = br_dev_init,
  5.     .ndo_uninit         = br_dev_uninit,
  6.     .ndo_start_xmit         = br_dev_xmit,
  7.     .ndo_get_stats64     = br_get_stats64,
  8.     .ndo_set_mac_address     = br_set_mac_address,
  9.     .ndo_set_rx_mode     = br_dev_set_multicast_list,
  10.     .ndo_change_rx_flags     = br_dev_change_rx_flags,
  11.     .ndo_change_mtu         = br_change_mtu,
  12.     .ndo_do_ioctl         = br_dev_ioctl,
  13. #ifdef CONFIG_NET_POLL_CONTROLLER
  14.     .ndo_netpoll_setup     = br_netpoll_setup,
  15.     .ndo_netpoll_cleanup     = br_netpoll_cleanup,
  16.     .ndo_poll_controller     = br_poll_controller,
  17. #endif
  18.     .ndo_add_slave         = br_add_slave,
  19.     .ndo_del_slave         = br_del_slave,
  20.     .ndo_fix_features = br_fix_features,
  21.     .ndo_fdb_add         = br_fdb_add,
  22.     .ndo_fdb_del         = br_fdb_delete,
  23.     .ndo_fdb_dump         = br_fdb_dump,
  24.     .ndo_bridge_getlink     = br_getlink,
  25.     .ndo_bridge_setlink     = br_setlink,
  26.     .ndo_bridge_dellink     = br_dellink,
  27.     .ndo_features_check     = passthru_features_check,
  28. };

4.6 static int br_add_slave(struct net_device *dev, struct net_device *slave_dev,struct netlink_ext_ack *extack)

点击(此处)折叠或打开

  1. static int br_add_slave(struct net_device *dev, struct net_device *slave_dev,
  2.             struct netlink_ext_ack *extack)

  3. {
  4.     struct net_bridge *br = netdev_priv(dev);

  5.     return br_add_if(br, slave_dev, extack);
  6. }

4.7  int br_add_if(struct net_bridge *br, struct net_device *dev, struct netlink_ext_ack *extack)

点击(此处)折叠或打开

  1. int br_add_if(struct net_bridge *br, struct net_device *dev,
  2.      struct netlink_ext_ack *extack)
  3. {
  4.     struct net_bridge_port *p;
  5.     int err = 0;
  6.     unsigned br_hr, dev_hr;
  7.     bool changed_addr;

  8.     /* Don't allow bridging non-ethernet like devices, or DSA-enabled
  9.      * master network devices since the bridge layer rx_handler prevents
  10.      * the DSA fake ethertype handler to be invoked, so we do not strip off
  11.      * the DSA switch tag protocol header and the bridge layer just return
  12.      * RX_HANDLER_CONSUMED, stopping RX processing for these frames.
  13.      */
  14.     if ((dev->flags & IFF_LOOPBACK) ||
  15.      dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN ||
  16.      !is_valid_ether_addr(dev->dev_addr) ||
  17.      netdev_uses_dsa(dev))
  18.         return -EINVAL;

  19.     /* No bridging of bridges */
  20.     if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) {
  21.         NL_SET_ERR_MSG(extack,
  22.              "Can not enslave a bridge to a bridge");
  23.         return -ELOOP;
  24.     }

  25.     /* Device has master upper dev */
  26.     if (netdev_master_upper_dev_get(dev))
  27.         return -EBUSY;

  28.     /* No bridging devices that dislike that (e.g. wireless) */
  29.     if (dev->priv_flags & IFF_DONT_BRIDGE) {
  30.         NL_SET_ERR_MSG(extack,
  31.              "Device does not allow enslaving to a bridge");
  32.         return -EOPNOTSUPP;
  33.     }

  34.     p = new_nbp(br, dev);
  35.     if (IS_ERR(p))
  36.         return PTR_ERR(p);

  37.     call_netdevice_notifiers(NETDEV_JOIN, dev);

  38.     err = dev_set_allmulti(dev, 1);
  39.     if (err)
  40.         goto put_back;

  41.     err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
  42.                  SYSFS_BRIDGE_PORT_ATTR);
  43.     if (err)
  44.         goto err1;

  45.     err = br_sysfs_addif(p);
  46.     if (err)
  47.         goto err2;

  48.     err = br_netpoll_enable(p);
  49.     if (err)
  50.         goto err3;

  51.     err = netdev_rx_handler_register(dev, br_handle_frame, p);
  52.     if (err)
  53.         goto err4;

  54.     dev->priv_flags |= IFF_BRIDGE_PORT;

  55.     err = netdev_master_upper_dev_link(dev, br->dev, NULL, NULL, extack);
  56.     if (err)
  57.         goto err5;

  58.     err = nbp_switchdev_mark_set(p);
  59.     if (err)
  60.         goto err6;

  61.     dev_disable_lro(dev);

  62.     list_add_rcu(&p->list, &br->port_list);

  63.     nbp_update_port_count(br);

  64.     netdev_update_features(br->dev);

  65.     br_hr = br->dev->needed_headroom;
  66.     dev_hr = netdev_get_fwd_headroom(dev);
  67.     if (br_hr < dev_hr)
  68.         update_headroom(br, dev_hr);
  69.     else
  70.         netdev_set_rx_headroom(dev, br_hr);

  71.     if (br_fdb_insert(br, p, dev->dev_addr, 0))
  72.         netdev_err(dev, "failed insert local address bridge forwarding table\n");

  73.     err = nbp_vlan_init(p);
  74.     if (err) {
  75.         netdev_err(dev, "failed to initialize vlan filtering on this port\n");
  76.         goto err7;
  77.     }

  78.     spin_lock_bh(&br->lock);
  79.     changed_addr = br_stp_recalculate_bridge_id(br);

  80.     if (netif_running(dev) && netif_oper_up(dev) &&
  81.      (br->dev->flags & IFF_UP))
  82.         br_stp_enable_port(p);
  83.     spin_unlock_bh(&br->lock);

  84.     br_ifinfo_notify(RTM_NEWLINK, NULL, p);

  85.     if (changed_addr)
  86.         call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);

  87.     br_mtu_auto_adjust(br);
  88.     br_set_gso_limits(br);

  89.     kobject_uevent(&p->kobj, KOBJ_ADD);

  90.     return 0;

  91. err7:
  92.     list_del_rcu(&p->list);
  93.     br_fdb_delete_by_port(br, p, 0, 1);
  94.     nbp_update_port_count(br);
  95. err6:
  96.     netdev_upper_dev_unlink(dev, br->dev);
  97. err5:
  98.     dev->priv_flags &= ~IFF_BRIDGE_PORT;
  99.     netdev_rx_handler_unregister(dev);
  100. err4:
  101.     br_netpoll_disable(p);
  102. err3:
  103.     sysfs_remove_link(br->ifobj, p->dev->name);
  104. err2:
  105.     kobject_put(&p->kobj);
  106.     p = NULL; /* kobject_put frees */
  107. err1:
  108.     dev_set_allmulti(dev, -1);
  109. put_back:
  110.     dev_put(dev);
  111.     kfree(p);
  112.     return err;
  113. }










阅读(10709) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:没有了

给主人留下些什么吧!~~