From patchwork Wed Dec 23 23:45:28 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Octavian Purdila X-Patchwork-Id: 41730 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id E9111B7BF2 for ; Thu, 24 Dec 2009 10:49:58 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757570AbZLWXtb (ORCPT ); Wed, 23 Dec 2009 18:49:31 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1757519AbZLWXtF (ORCPT ); Wed, 23 Dec 2009 18:49:05 -0500 Received: from ixro-out-rtc.ixiacom.com ([92.87.192.98]:23684 "EHLO ixro-ex1.ixiacom.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1757526AbZLWXs6 (ORCPT ); Wed, 23 Dec 2009 18:48:58 -0500 Received: from localhost.localdomain ([10.205.9.170]) by ixro-ex1.ixiacom.com with Microsoft SMTPSVC(6.0.3790.3959); Thu, 24 Dec 2009 01:48:52 +0200 From: Octavian Purdila To: netdev@vger.kernel.org Cc: Arnaldo Carvalho de Melo , Eric Dumazet , Octavian Purdila Subject: [net-next PATCH v2 3/9] llc: add support for SO_BINDTODEVICE Date: Thu, 24 Dec 2009 01:45:28 +0200 Message-Id: <1261611934-24348-4-git-send-email-opurdila@ixiacom.com> X-Mailer: git-send-email 1.5.6.5 In-Reply-To: <1261611934-24348-1-git-send-email-opurdila@ixiacom.com> References: <1261611934-24348-1-git-send-email-opurdila@ixiacom.com> X-OriginalArrivalTime: 23 Dec 2009 23:48:52.0884 (UTC) FILETIME=[7B7E2D40:01CA842A] Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Using bind(MAC address) with LLC sockets has O(n) complexity, where n is the number of interfaces. To overcome this, we add support for SO_BINDTODEVICE which drops the complexity to O(1). Signed-off-by: Octavian Purdila --- net/llc/af_llc.c | 29 +++++++++++++++++++++++++++-- 1 files changed, 27 insertions(+), 2 deletions(-) diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index ac691fe..c4d1a1d 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -259,7 +259,14 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) if (!sock_flag(sk, SOCK_ZAPPED)) goto out; rc = -ENODEV; - llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); + if (sk->sk_bound_dev_if) { + llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); + if (llc->dev && addr->sllc_arphrd != llc->dev->type) { + dev_put(llc->dev); + llc->dev = NULL; + } + } else + llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); if (!llc->dev) goto out; rc = -EUSERS; @@ -310,7 +317,25 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) goto out; rc = -ENODEV; rtnl_lock(); - llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, addr->sllc_mac); + if (sk->sk_bound_dev_if) { + llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); + if (llc->dev) { + if (!addr->sllc_arphrd) + addr->sllc_arphrd = llc->dev->type; + if (llc_mac_null(addr->sllc_mac)) + memcpy(addr->sllc_mac, llc->dev->dev_addr, + IFHWADDRLEN); + if (addr->sllc_arphrd != llc->dev->type || + !llc_mac_match(addr->sllc_mac, + llc->dev->dev_addr)) { + rc = -EINVAL; + dev_put(llc->dev); + llc->dev = NULL; + } + } + } else + llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, + addr->sllc_mac); rtnl_unlock(); if (!llc->dev) goto out;