]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: VirtioNetDxe: map multicast IP to MAC: SNP.McastIpToMac
authorLaszlo Ersek <lersek@redhat.com>
Fri, 14 Jun 2013 07:40:30 +0000 (07:40 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 14 Jun 2013 07:40:30 +0000 (07:40 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14414 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/VirtioNetDxe/SnpMcastIpToMac.c [new file with mode: 0644]

diff --git a/OvmfPkg/VirtioNetDxe/SnpMcastIpToMac.c b/OvmfPkg/VirtioNetDxe/SnpMcastIpToMac.c
new file mode 100644 (file)
index 0000000..686fd0d
--- /dev/null
@@ -0,0 +1,108 @@
+/** @file\r
+\r
+  Implementation of the SNP.McastIpToMac() function and its private helpers if\r
+  any.\r
+\r
+  Copyright (C) 2013, Red Hat, Inc.\r
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+\r
+  This program and the accompanying materials are licensed and made available\r
+  under the terms and conditions of the BSD License which accompanies this\r
+  distribution. The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include "VirtioNet.h"\r
+\r
+/**\r
+  Converts a multicast IP address to a multicast HW MAC address.\r
+\r
+  @param  This The protocol instance pointer.\r
+  @param  IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set\r
+               to FALSE if the multicast IP address is IPv4 [RFC 791].\r
+  @param  IP   The multicast IP address that is to be converted to a multicast\r
+               HW MAC address.\r
+  @param  MAC  The multicast HW MAC address that is to be generated from IP.\r
+\r
+  @retval EFI_SUCCESS           The multicast IP address was mapped to the\r
+                                multicast HW MAC address.\r
+  @retval EFI_NOT_STARTED       The network interface has not been started.\r
+  @retval EFI_BUFFER_TOO_SMALL  The Statistics buffer was too small. The\r
+                                current buffer size needed to hold the\r
+                                statistics is returned in StatisticsSize.\r
+  @retval EFI_INVALID_PARAMETER One or more of the parameters has an\r
+                                unsupported value.\r
+  @retval EFI_DEVICE_ERROR      The command could not be sent to the network\r
+                                interface.\r
+  @retval EFI_UNSUPPORTED       This function is not supported by the network\r
+                                interface.\r
+\r
+**/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VirtioNetMcastIpToMac (\r
+  IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+  IN BOOLEAN                     IPv6,\r
+  IN EFI_IP_ADDRESS              *Ip,\r
+  OUT EFI_MAC_ADDRESS            *Mac\r
+  )\r
+{\r
+  VNET_DEV   *Dev;\r
+  EFI_TPL    OldTpl;\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  // http://en.wikipedia.org/wiki/Multicast_address\r
+  //\r
+  if (This == NULL || Ip == NULL || Mac == NULL ||\r
+      ( IPv6 && (Ip->v6.Addr[0]       ) != 0xFF) || // invalid IPv6 mcast addr\r
+      (!IPv6 && (Ip->v4.Addr[0] & 0xF0) != 0xE0)    // invalid IPv4 mcast addr\r
+      ) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Dev = VIRTIO_NET_FROM_SNP (This);\r
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+  switch (Dev->Snm.State) {\r
+  case EfiSimpleNetworkStopped:\r
+    Status = EFI_NOT_STARTED;\r
+    goto Exit;\r
+  case EfiSimpleNetworkStarted:\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Exit;\r
+  default:\r
+    break;\r
+  }\r
+\r
+  //\r
+  // http://en.wikipedia.org/wiki/IP_multicast#Layer_2_delivery\r
+  //\r
+  if (IPv6) {\r
+    Mac->Addr[0] = 0x33;\r
+    Mac->Addr[1] = 0x33;\r
+    Mac->Addr[2] = Ip->v6.Addr[12];\r
+    Mac->Addr[3] = Ip->v6.Addr[13];\r
+    Mac->Addr[4] = Ip->v6.Addr[14];\r
+    Mac->Addr[5] = Ip->v6.Addr[15];\r
+  }\r
+  else {\r
+    Mac->Addr[0] = 0x01;\r
+    Mac->Addr[1] = 0x00;\r
+    Mac->Addr[2] = 0x5E;\r
+    Mac->Addr[3] = Ip->v4.Addr[1] & 0x7F;\r
+    Mac->Addr[4] = Ip->v4.Addr[2];\r
+    Mac->Addr[5] = Ip->v4.Addr[3];\r
+  }\r
+  Status = EFI_SUCCESS;\r
+\r
+Exit:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r